From 4893e41de21dddee88f30d1407080724079e82a4 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Mon, 5 Jul 2021 00:48:11 +0400 Subject: [PATCH] Refactoring [skip ci] --- .../Sources/BotCheckoutControllerNode.swift | 6 +- .../BotCheckoutPasswordEntryController.swift | 2 +- .../Sources/ChatImportActivityScreen.swift | 20 +- .../Sources/ChatListController.swift | 2 +- .../GalleryUI/Sources/GalleryController.swift | 2 +- .../SecretMediaPreviewController.swift | 2 +- .../GameUI/Sources/GameControllerNode.swift | 2 +- .../Sources/SecureIdAuthController.swift | 4 +- .../Sources/ResetPasswordController.swift | 4 +- .../SetupTwoStepVerificationController.swift | 18 +- ...tupTwoStepVerificationControllerNode.swift | 40 ++- .../TwoFactorAuthDataInputScreen.swift | 255 +++++++++--------- .../Sources/TwoFactorAuthSplashScreen.swift | 8 +- .../ChannelPermissionsController.swift | 4 +- .../Sources/GroupsInCommonController.swift | 244 ----------------- .../Sources/PeerReportController.swift | 12 +- .../CreatePasswordController.swift | 4 +- .../PrivacyAndSecurityController.swift | 4 +- ...pVerificationPasswordEntryController.swift | 4 +- .../TwoStepVerificationResetController.swift | 4 +- .../TwoStepVerificationUnlockController.swift | 42 +-- .../Sources/CallFeedbackController.swift | 2 +- .../Sources/CallRatingController.swift | 12 +- submodules/TelegramCore/Sources/Account.swift | 4 +- .../TelegramCore/Sources/Authorization.swift | 4 +- .../Sources/ChannelOwnershipTransfer.swift | 2 +- .../Sources/ChatHistoryImport.swift | 244 ----------------- .../GlobalTelegramCoreConfiguration.swift | 5 - ...essageAutoremoveTimeoutInteractively.swift | 4 +- .../Sources/State/CallSessionManager.swift | 2 +- .../State/SynchronizePeerReadState.swift | 4 - .../Auth}/ConfirmTwoStepRecoveryEmail.swift | 6 +- .../Auth/TelegramEngineAuth.swift | 145 +++++++++- .../Auth}/TwoStepVerification.swift | 42 +-- .../{ => TelegramEngine/Calls}/RateCall.swift | 4 +- .../Calls/TelegramEngineCalls.swift | 19 ++ .../TelegramEngineHistoryImport.swift | 255 ++++++++++++++++++ .../Messages}/ForwardGame.swift | 2 +- .../RequestMessageActionCallback.swift | 2 +- .../Messages/TelegramEngineMessages.swift | 9 + .../Peers}/GroupsInCommon.swift | 33 --- .../Peers}/ReportPeer.swift | 12 +- .../{ => TelegramEngine/Peers}/SlowMode.swift | 2 +- .../Peers/TelegramEnginePeers.swift | 36 ++- .../Privacy}/BlockedPeers.swift | 2 +- .../Privacy}/BlockedPeersContext.swift | 1 - .../Privacy/TelegramEnginePrivacy.swift | 16 ++ .../SecureId/AccessSecureId.swift | 2 +- .../SecureId/SaveSecureIdValue.swift | 2 +- .../TelegramEngine/TelegramEngine.swift | 17 ++ .../AuthorizationSequenceController.swift | 2 +- .../TelegramUI/Sources/ChatController.swift | 22 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 10 +- .../Sources/ShareExtensionContext.swift | 12 +- .../Sources/OngoingCallContext.swift | 2 +- .../Sources/WatchRequestHandlers.swift | 2 +- 56 files changed, 783 insertions(+), 840 deletions(-) delete mode 100644 submodules/PeerInfoUI/Sources/GroupsInCommonController.swift delete mode 100644 submodules/TelegramCore/Sources/ChatHistoryImport.swift delete mode 100644 submodules/TelegramCore/Sources/GlobalTelegramCoreConfiguration.swift rename submodules/TelegramCore/Sources/{ => SecretChats}/SetSecretChatMessageAutoremoveTimeoutInteractively.swift (88%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Auth}/ConfirmTwoStepRecoveryEmail.swift (80%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Auth}/TwoStepVerification.swift (90%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Calls}/RateCall.swift (75%) create mode 100644 submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift create mode 100644 submodules/TelegramCore/Sources/TelegramEngine/HistoryImport/TelegramEngineHistoryImport.swift rename submodules/TelegramCore/Sources/{ => TelegramEngine/Messages}/ForwardGame.swift (89%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Peers}/GroupsInCommon.swift (79%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Peers}/ReportPeer.swift (93%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Peers}/SlowMode.swift (86%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Privacy}/BlockedPeers.swift (96%) rename submodules/TelegramCore/Sources/{ => TelegramEngine/Privacy}/BlockedPeersContext.swift (99%) create mode 100644 submodules/TelegramCore/Sources/TelegramEngine/Privacy/TelegramEnginePrivacy.swift diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift index 04c5a591e2..bef77594c3 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutControllerNode.swift @@ -944,7 +944,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz self.listNode.supernode?.insertSubnode(self.inProgressDimNode, aboveSubnode: self.listNode) - self.passwordTipDisposable = (twoStepVerificationConfiguration(account: self.context.account) + self.passwordTipDisposable = (self.context.engine.auth.twoStepVerificationConfiguration() |> deliverOnMainQueue).start(next: { [weak self] value in guard let strongSelf = self else { return @@ -1069,7 +1069,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz if let savedCredentialsToken = savedCredentialsToken { credentials = .saved(id: id, tempPassword: savedCredentialsToken.token) } else { - let _ = (cachedTwoStepPasswordToken(postbox: self.context.account.postbox) + let _ = (self.context.engine.auth.cachedTwoStepPasswordToken() |> deliverOnMainQueue).start(next: { [weak self] token in if let strongSelf = self { let timestamp = strongSelf.context.account.network.getApproximateRemoteTimestamp() @@ -1340,7 +1340,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz }), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Yes, action: { if let strongSelf = self { - let _ = cacheTwoStepPasswordToken(postbox: strongSelf.context.account.postbox, token: token).start() + let _ = strongSelf.context.engine.auth.cacheTwoStepPasswordToken(token: token).start() strongSelf.pay(savedCredentialsToken: token) } }) diff --git a/submodules/BotPaymentsUI/Sources/BotCheckoutPasswordEntryController.swift b/submodules/BotPaymentsUI/Sources/BotCheckoutPasswordEntryController.swift index 7485437a0c..c2c0a5733e 100644 --- a/submodules/BotPaymentsUI/Sources/BotCheckoutPasswordEntryController.swift +++ b/submodules/BotPaymentsUI/Sources/BotCheckoutPasswordEntryController.swift @@ -285,7 +285,7 @@ private final class BotCheckoutPasswordAlertContentNode: AlertContentNode { } self.isVerifying = true - self.disposable.set((requestTemporaryTwoStepPasswordToken(account: self.context.account, password: text, period: self.period, requiresBiometrics: self.requiresBiometrics) |> deliverOnMainQueue).start(next: { [weak self] token in + self.disposable.set((self.context.engine.auth.requestTemporaryTwoStepPasswordToken(password: text, period: self.period, requiresBiometrics: self.requiresBiometrics) |> deliverOnMainQueue).start(next: { [weak self] token in if let strongSelf = self { strongSelf.completion(token) } diff --git a/submodules/ChatImportUI/Sources/ChatImportActivityScreen.swift b/submodules/ChatImportUI/Sources/ChatImportActivityScreen.swift index ec7421a578..5cefdf43e0 100644 --- a/submodules/ChatImportUI/Sources/ChatImportActivityScreen.swift +++ b/submodules/ChatImportUI/Sources/ChatImportActivityScreen.swift @@ -68,16 +68,16 @@ private final class ImportManager { private let account: Account private let archivePath: String? - private let entries: [(SSZipEntry, String, ChatHistoryImport.MediaType)] + private let entries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)] - private var session: ChatHistoryImport.Session? + private var session: TelegramEngine.HistoryImport.Session? private let disposable = MetaDisposable() private let totalBytes: Int private let totalMediaBytes: Int private let mainFileSize: Int - private var pendingEntries: [(SSZipEntry, String, ChatHistoryImport.MediaType)] + private var pendingEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)] private var entryProgress: [String: (Int, Int)] = [:] private var activeEntries: [String: Disposable] = [:] @@ -91,7 +91,7 @@ private final class ImportManager { return self.statePromise.get() } - init(account: Account, peerId: PeerId, mainFile: TempBoxFile, archivePath: String?, entries: [(SSZipEntry, String, ChatHistoryImport.MediaType)]) { + init(account: Account, peerId: PeerId, mainFile: TempBoxFile, archivePath: String?, entries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)]) { self.account = account self.archivePath = archivePath self.entries = entries @@ -114,7 +114,7 @@ private final class ImportManager { Logger.shared.log("ChatImportScreen", " \(entry.1)") } - self.disposable.set((ChatHistoryImport.initSession(account: self.account, peerId: peerId, file: mainFile, mediaCount: Int32(entries.count)) + self.disposable.set((TelegramEngine(account: self.account).historyImport.initSession(peerId: peerId, file: mainFile, mediaCount: Int32(entries.count)) |> mapError { error -> ImportError in switch error { case .chatAdminRequired: @@ -180,7 +180,7 @@ private final class ImportManager { self.failWithError(.generic) return } - self.disposable.set((ChatHistoryImport.startImport(account: self.account, session: session) + self.disposable.set((TelegramEngine(account: self.account).historyImport.startImport(session: session) |> deliverOnMainQueue).start(error: { [weak self] _ in guard let strongSelf = self else { return @@ -258,7 +258,7 @@ private final class ImportManager { if !pathExtension.isEmpty, let value = TGMimeTypeMap.mimeType(forExtension: pathExtension) { mimeType = value } - return ChatHistoryImport.uploadMedia(account: account, session: session, file: tempFile, disposeFileAfterDone: true, fileName: entry.0.path, mimeType: mimeType, type: entry.2) + return TelegramEngine(account: account).historyImport.uploadMedia(session: session, file: tempFile, disposeFileAfterDone: true, fileName: entry.0.path, mimeType: mimeType, type: entry.2) |> mapError { error -> ImportError in switch error { case .chatAdminRequired: @@ -732,7 +732,7 @@ public final class ChatImportActivityScreen: ViewController { private let mainEntry: TempBoxFile private let totalBytes: Int private let totalMediaBytes: Int - private let otherEntries: [(SSZipEntry, String, ChatHistoryImport.MediaType)] + private let otherEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)] private var importManager: ImportManager? private var progressEstimator: ProgressEstimator? @@ -749,14 +749,14 @@ public final class ChatImportActivityScreen: ViewController { } } - public init(context: AccountContext, cancel: @escaping () -> Void, peerId: PeerId, archivePath: String?, mainEntry: TempBoxFile, otherEntries: [(SSZipEntry, String, ChatHistoryImport.MediaType)]) { + public init(context: AccountContext, cancel: @escaping () -> Void, peerId: PeerId, archivePath: String?, mainEntry: TempBoxFile, otherEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)]) { self.context = context self.cancel = cancel self.peerId = peerId self.archivePath = archivePath self.mainEntry = mainEntry - self.otherEntries = otherEntries.map { entry -> (SSZipEntry, String, ChatHistoryImport.MediaType) in + self.otherEntries = otherEntries.map { entry -> (SSZipEntry, String, TelegramEngine.HistoryImport.MediaType) in return (entry.0, entry.1, entry.2) } diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index 07c1764a1f..08d9573d76 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -2448,7 +2448,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController guard let strongSelf = self else { return } - let _ = requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.peerId, isBlocked: true).start() + let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.peerId, isBlocked: true).start() }) } })) diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index 4645ed80cb..d55e5ff53f 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -885,7 +885,7 @@ public class GalleryController: ViewController, StandalonePresentableController self.screenCaptureEventsDisposable = (screenCaptureEvents() |> deliverOnMainQueue).start(next: { [weak self] _ in if let strongSelf = self, strongSelf.traceVisibility() { - let _ = addSecretChatMessageScreenshot(account: strongSelf.context.account, peerId: id.peerId).start() + let _ = strongSelf.context.engine.messages.addSecretChatMessageScreenshot(peerId: id.peerId).start() } }) } diff --git a/submodules/GalleryUI/Sources/SecretMediaPreviewController.swift b/submodules/GalleryUI/Sources/SecretMediaPreviewController.swift index 815dbeecf5..9ff8e0da6d 100644 --- a/submodules/GalleryUI/Sources/SecretMediaPreviewController.swift +++ b/submodules/GalleryUI/Sources/SecretMediaPreviewController.swift @@ -351,7 +351,7 @@ public final class SecretMediaPreviewController: ViewController { if strongSelf.messageId.peerId.namespace == Namespaces.Peer.CloudUser { let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.messageId.peerId, messages: [.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaAction(action: TelegramMediaActionType.historyScreenshot)), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start() } else if strongSelf.messageId.peerId.namespace == Namespaces.Peer.SecretChat { - let _ = addSecretChatMessageScreenshot(account: strongSelf.context.account, peerId: strongSelf.messageId.peerId).start() + let _ = strongSelf.context.engine.messages.addSecretChatMessageScreenshot(peerId: strongSelf.messageId.peerId).start() } } }) diff --git a/submodules/GameUI/Sources/GameControllerNode.swift b/submodules/GameUI/Sources/GameControllerNode.swift index 51be76923e..02ef5c9839 100644 --- a/submodules/GameUI/Sources/GameControllerNode.swift +++ b/submodules/GameUI/Sources/GameControllerNode.swift @@ -147,7 +147,7 @@ final class GameControllerNode: ViewControllerTracingNode { if eventName == "share_score" { self.present(ShareController(context: self.context, subject: .fromExternal({ [weak self] peerIds, text, account in if let strongSelf = self { - let signals = peerIds.map { forwardGameWithScore(account: account, messageId: strongSelf.message.id, to: $0) } + let signals = peerIds.map { TelegramEngine(account: account).messages.forwardGameWithScore(messageId: strongSelf.message.id, to: $0) } return .single(.preparing) |> then( combineLatest(signals) diff --git a/submodules/PassportUI/Sources/SecureIdAuthController.swift b/submodules/PassportUI/Sources/SecureIdAuthController.swift index 4396f704cd..0a2febc1b9 100644 --- a/submodules/PassportUI/Sources/SecureIdAuthController.swift +++ b/submodules/PassportUI/Sources/SecureIdAuthController.swift @@ -122,7 +122,7 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable } self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationInfoIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.infoPressed)) - self.challengeDisposable.set((twoStepAuthData(context.account.network) + self.challengeDisposable.set((context.engine.auth.twoStepAuthData() |> deliverOnMainQueue).start(next: { [weak self] data in if let strongSelf = self { let storedPassword = context.getStoredSecureIdPassword() @@ -512,7 +512,7 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable guard let strongSelf = self else { return } - strongSelf.recoveryDisposable.set((requestTwoStepVerificationPasswordRecoveryCode(network: strongSelf.context.account.network) + strongSelf.recoveryDisposable.set((strongSelf.context.engine.auth.requestTwoStepVerificationPasswordRecoveryCode() |> deliverOnMainQueue).start(next: { emailPattern in guard let strongSelf = self else { return diff --git a/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift b/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift index a751dc16da..2b9d5e155a 100644 --- a/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift +++ b/submodules/PasswordSetupUI/Sources/ResetPasswordController.swift @@ -140,7 +140,7 @@ public func resetPasswordController(context: AccountContext, emailPattern: Strin let presentationData = context.sharedContext.currentPresentationData.with { $0 } presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetTitle, text: presentationData.strings.TwoStepAuth_RecoveryEmailResetText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetAction, action: { - let _ = (requestTwoStepPasswordReset(network: context.account.network) + let _ = (context.engine.auth.requestTwoStepPasswordReset() |> deliverOnMainQueue).start(next: { result in switch result { case .done, .waitingForReset: @@ -179,7 +179,7 @@ public func resetPasswordController(context: AccountContext, emailPattern: Strin state.checking = true return state } - saveDisposable.set((recoverTwoStepVerificationPassword(network: context.account.network, code: state.code) + saveDisposable.set((context.engine.auth.recoverTwoStepVerificationPassword(code: state.code) |> deliverOnMainQueue).start(error: { error in updateState { state in var state = state diff --git a/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationController.swift b/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationController.swift index 4326df99b4..478e8abc9d 100644 --- a/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationController.swift +++ b/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationController.swift @@ -11,8 +11,7 @@ import ProgressNavigationButtonNode import AccountContext public class SetupTwoStepVerificationController: ViewController { - private let network: Network - private let sharedContext: SharedAccountContext + private let context: AccountContext private let initialState: SetupTwoStepVerificationInitialState private let stateUpdated: (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void @@ -33,19 +32,14 @@ public class SetupTwoStepVerificationController: ViewController { private var presentationData: PresentationData private var presentationDataDisposable: Disposable? - - convenience public init(context: AccountContext, initialState: SetupTwoStepVerificationInitialState, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void) { - self.init(sharedContext: context.sharedContext, network: context.account.network, initialState: initialState, stateUpdated: stateUpdated) - } - public init(sharedContext: SharedAccountContext, network: Network, initialState: SetupTwoStepVerificationInitialState, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void) { - self.sharedContext = sharedContext - self.network = network + public init(context: AccountContext, initialState: SetupTwoStepVerificationInitialState, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool, SetupTwoStepVerificationController) -> Void) { + self.context = context self.initialState = initialState self.stateUpdated = stateUpdated - self.presentationData = self.sharedContext.currentPresentationData.with { $0 } + self.presentationData = self.context.sharedContext.currentPresentationData.with { $0 } super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: NavigationBarTheme(buttonColor: self.presentationData.theme.rootController.navigationBar.accentTextColor, disabledButtonColor: self.presentationData.theme.rootController.navigationBar.disabledButtonColor, primaryTextColor: self.presentationData.theme.rootController.navigationBar.primaryTextColor, backgroundColor: .clear, enableBackgroundBlur: false, separatorColor: .clear, badgeBackgroundColor: .clear, badgeStrokeColor: .clear, badgeTextColor: .clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings))) @@ -53,7 +47,7 @@ public class SetupTwoStepVerificationController: ViewController { self.navigationItem.setLeftBarButton(UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false) - self.presentationDataDisposable = (self.sharedContext.presentationData + self.presentationDataDisposable = (self.context.sharedContext.presentationData |> deliverOnMainQueue).start(next: { [weak self] presentationData in if let strongSelf = self { let previousTheme = strongSelf.presentationData.theme @@ -103,7 +97,7 @@ public class SetupTwoStepVerificationController: ViewController { } override public func loadDisplayNode() { - self.displayNode = SetupTwoStepVerificationControllerNode(sharedContext: self.sharedContext, network: self.network, updateBackAction: { [weak self] action in + self.displayNode = SetupTwoStepVerificationControllerNode(context: self.context, updateBackAction: { [weak self] action in guard let strongSelf = self else { return } diff --git a/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationControllerNode.swift b/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationControllerNode.swift index 90fb0a7ed7..0b1605df28 100644 --- a/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationControllerNode.swift +++ b/submodules/PasswordSetupUI/Sources/SetupTwoStepVerificationControllerNode.swift @@ -141,8 +141,7 @@ public enum SetupTwoStepVerificationStateUpdate { } final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { - private let sharedContext: SharedAccountContext - private let network: Network + private let context: AccountContext private var presentationData: PresentationData private let updateBackAction: (Bool) -> Void private let updateNextAction: (SetupTwoStepVerificationNextAction) -> Void @@ -155,15 +154,14 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { private var contentNode: SetupTwoStepVerificationContentNode? private let actionDisposable = MetaDisposable() - init(sharedContext: SharedAccountContext, network: Network, updateBackAction: @escaping (Bool) -> Void, updateNextAction: @escaping (SetupTwoStepVerificationNextAction) -> Void, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool) -> Void, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void, initialState: SetupTwoStepVerificationInitialState) { - self.sharedContext = sharedContext - self.network = network + init(context: AccountContext, updateBackAction: @escaping (Bool) -> Void, updateNextAction: @escaping (SetupTwoStepVerificationNextAction) -> Void, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate, Bool) -> Void, present: @escaping (ViewController, Any?) -> Void, dismiss: @escaping () -> Void, initialState: SetupTwoStepVerificationInitialState) { + self.context = context self.updateBackAction = updateBackAction self.updateNextAction = updateNextAction self.stateUpdated = stateUpdated self.present = present self.dismiss = dismiss - self.presentationData = self.sharedContext.currentPresentationData.with { $0 } + self.presentationData = self.context.sharedContext.currentPresentationData.with { $0 } self.innerState = SetupTwoStepVerificationControllerInnerState(layout: nil, data: SetupTwoStepVerificationControllerDataState(activity: false, state: SetupTwoStepVerificationState(initialState: initialState))) self.activityIndicator = ActivityIndicator(type: .custom(self.presentationData.theme.list.itemAccentColor, 22.0, 2.0, false)) @@ -173,7 +171,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { self.processStateUpdated() if self.innerState.data.state == nil { - self.actionDisposable.set((twoStepAuthData(self.network) + self.actionDisposable.set((self.context.engine.auth.twoStepAuthData() |> deliverOnMainQueue).start(next: { [weak self] data in guard let strongSelf = self else { return @@ -342,7 +340,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { state.data.activity = true return state }, transition: .animated(duration: 0.5, curve: .spring)) - strongSelf.actionDisposable.set((updateTwoStepVerificationPassword(network: strongSelf.network, currentPassword: nil, updatedPassword: .none) + strongSelf.actionDisposable.set((strongSelf.context.engine.auth.updateTwoStepVerificationPassword(currentPassword: nil, updatedPassword: .none) |> deliverOnMainQueue).start(next: { _ in guard let strongSelf = self else { return @@ -358,7 +356,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) strongSelf.updateState({ state in var state = state state.data.activity = false @@ -395,7 +393,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { state.data.activity = true return state }, transition: .animated(duration: 0.5, curve: .spring)) - strongSelf.actionDisposable.set((resendTwoStepRecoveryEmail(network: strongSelf.network) + strongSelf.actionDisposable.set((strongSelf.context.engine.auth.resendTwoStepRecoveryEmail() |> deliverOnMainQueue).start(error: { error in guard let strongSelf = self else { return @@ -407,7 +405,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { case .generic: text = strongSelf.presentationData.strings.Login_UnknownError } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) strongSelf.updateState({ state in var state = state state.data.activity = false @@ -528,7 +526,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { if password == confirmation { state.data.state = .enterHint(mode: mode, password: password, hint: "") } else { - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: strongSelf.presentationData.strings.TwoStepAuth_SetupPasswordConfirmFailed, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: strongSelf.presentationData.strings.TwoStepAuth_SetupPasswordConfirmFailed, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) } case let .enterHint(mode, password, hint): switch mode { @@ -536,7 +534,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { state.data.state = .enterEmail(state: .create(password: password, hint: hint), email: "") case let .update(current, hasRecoveryEmail, hasSecureValues): state.data.activity = true - strongSelf.actionDisposable.set((updateTwoStepVerificationPassword(network: strongSelf.network, currentPassword: current, updatedPassword: .password(password: password, hint: hint, email: nil)) + strongSelf.actionDisposable.set((strongSelf.context.engine.auth.updateTwoStepVerificationPassword(currentPassword: current, updatedPassword: .password(password: password, hint: hint, email: nil)) |> deliverOnMainQueue).start(next: { result in guard let strongSelf = self else { return @@ -560,7 +558,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) strongSelf.updateState({ state in var state = state state.data.activity = false @@ -572,7 +570,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { state.data.activity = true switch enterState { case let .create(password, hint): - strongSelf.actionDisposable.set((updateTwoStepVerificationPassword(network: strongSelf.network, currentPassword: nil, updatedPassword: .password(password: password, hint: hint, email: email)) + strongSelf.actionDisposable.set((strongSelf.context.engine.auth.updateTwoStepVerificationPassword(currentPassword: nil, updatedPassword: .password(password: password, hint: hint, email: email)) |> deliverOnMainQueue).start(next: { result in guard let strongSelf = self else { return @@ -604,7 +602,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { case .generic: text = strongSelf.presentationData.strings.Login_UnknownError } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) strongSelf.updateState({ state in var state = state state.data.activity = false @@ -620,7 +618,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { state.data.activity = true return state }, transition: .animated(duration: 0.5, curve: .spring)) - strongSelf.actionDisposable.set((updateTwoStepVerificationEmail(network: strongSelf.network, currentPassword: password, updatedEmail: email) + strongSelf.actionDisposable.set((strongSelf.context.engine.auth.updateTwoStepVerificationEmail(currentPassword: password, updatedEmail: email) |> deliverOnMainQueue).start(next: { result in guard let strongSelf = self else { return @@ -646,7 +644,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { guard let strongSelf = self else { return } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) strongSelf.updateState({ state in var state = state state.data.activity = false @@ -656,7 +654,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { } case let .confirmEmail(confirmState, _, _, code): state.data.activity = true - strongSelf.actionDisposable.set((confirmTwoStepRecoveryEmail(network: strongSelf.network, code: code) + strongSelf.actionDisposable.set((strongSelf.context.engine.auth.confirmTwoStepRecoveryEmail(code: code) |> deliverOnMainQueue).start(error: { error in guard let strongSelf = self else { return @@ -675,7 +673,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { case .generic: text = strongSelf.presentationData.strings.Login_UnknownError } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) + strongSelf.present(textAlertController(sharedContext: strongSelf.context.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil) strongSelf.updateState({ state in var state = state @@ -700,7 +698,7 @@ final class SetupTwoStepVerificationControllerNode: ViewControllerTracingNode { }, transition: .animated(duration: 0.5, curve: .spring)) } if case let .enterEmail(enterEmailState, enterEmailEmail)? = self.innerState.data.state, case .create = enterEmailState, enterEmailEmail.isEmpty { - self.present(textAlertController(sharedContext: self.sharedContext, title: nil, text: self.presentationData.strings.TwoStepAuth_EmailSkipAlert, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .destructiveAction, title: self.presentationData.strings.TwoStepAuth_EmailSkip, action: { + self.present(textAlertController(sharedContext: self.context.sharedContext, title: nil, text: self.presentationData.strings.TwoStepAuth_EmailSkipAlert, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .destructiveAction, title: self.presentationData.strings.TwoStepAuth_EmailSkip, action: { continueImpl() })]), nil) } else { diff --git a/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift b/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift index acb463f6e4..2d882e5c0c 100644 --- a/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift +++ b/submodules/PasswordSetupUI/Sources/TwoFactorAuthDataInputScreen.swift @@ -35,14 +35,14 @@ public enum TwoFactorDataInputMode { public final class TwoFactorDataInputScreen: ViewController { private let sharedContext: SharedAccountContext - private let network: Network + private let engine: SomeTelegramEngine private var presentationData: PresentationData private let mode: TwoFactorDataInputMode private let stateUpdated: (SetupTwoStepVerificationStateUpdate) -> Void - public init(sharedContext: SharedAccountContext, network: Network, mode: TwoFactorDataInputMode, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate) -> Void) { + public init(sharedContext: SharedAccountContext, engine: SomeTelegramEngine, mode: TwoFactorDataInputMode, stateUpdated: @escaping (SetupTwoStepVerificationStateUpdate) -> Void) { self.sharedContext = sharedContext - self.network = network + self.engine = engine self.mode = mode self.stateUpdated = stateUpdated @@ -101,7 +101,7 @@ public final class TwoFactorDataInputScreen: ViewController { } return true } - controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .passwordHint(recovery: nil, password: values[0]), stateUpdated: strongSelf.stateUpdated)) + controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: nil, password: values[0]), stateUpdated: strongSelf.stateUpdated)) navigationController.setViewControllers(controllers, animated: true) case let .passwordRecovery(recovery): let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText @@ -129,7 +129,7 @@ public final class TwoFactorDataInputScreen: ViewController { } return true } - controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .passwordHint(recovery: recovery, password: values[0]), stateUpdated: strongSelf.stateUpdated)) + controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: recovery, password: values[0]), stateUpdated: strongSelf.stateUpdated)) navigationController.setViewControllers(controllers, animated: true) case let .emailAddress(password, hint): guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else { @@ -138,7 +138,7 @@ public final class TwoFactorDataInputScreen: ViewController { let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil)) strongSelf.present(statusController, in: .window(.root)) - let _ = (updateTwoStepVerificationPassword(network: strongSelf.network, currentPassword: "", updatedPassword: .password(password: password, hint: hint, email: text)) + let _ = (strongSelf.engine.auth.updateTwoStepVerificationPassword(currentPassword: "", updatedPassword: .password(password: password, hint: hint, email: text)) |> deliverOnMainQueue).start(next: { [weak statusController] result in statusController?.dismiss() @@ -163,7 +163,7 @@ public final class TwoFactorDataInputScreen: ViewController { } return true } - controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .emailConfirmation(passwordAndHint: (password, hint), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init)), stateUpdated: strongSelf.stateUpdated)) + controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailConfirmation(passwordAndHint: (password, hint), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init)), stateUpdated: strongSelf.stateUpdated)) navigationController.setViewControllers(controllers, animated: true) } else { guard let navigationController = strongSelf.navigationController as? NavigationController else { @@ -178,7 +178,7 @@ public final class TwoFactorDataInputScreen: ViewController { } return true } - controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .done)) + controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done)) navigationController.setViewControllers(controllers, animated: true) } } @@ -205,120 +205,130 @@ public final class TwoFactorDataInputScreen: ViewController { } let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil)) strongSelf.present(statusController, in: .window(.root)) - - let _ = (updateTwoStepVerificationEmail(network: strongSelf.network, currentPassword: password, updatedEmail: text) - |> deliverOnMainQueue).start(next: { [weak statusController] result in - statusController?.dismiss() - - guard let strongSelf = self else { - return - } - - switch result { - case .none: - break - case let .password(_, pendingEmail): - if let pendingEmail = pendingEmail { - guard let navigationController = strongSelf.navigationController as? NavigationController else { - return - } - var controllers = navigationController.viewControllers.filter { controller in - if controller is TwoFactorAuthSplashScreen { - return false - } - if controller is TwoFactorDataInputScreen { - return false - } - return true - } - controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .emailConfirmation(passwordAndHint: (password, ""), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init)), stateUpdated: strongSelf.stateUpdated)) - navigationController.setViewControllers(controllers, animated: true) - } else { - guard let navigationController = strongSelf.navigationController as? NavigationController else { - return - } - var controllers = navigationController.viewControllers.filter { controller in - if controller is TwoFactorAuthSplashScreen { - return false - } - if controller is TwoFactorDataInputScreen { - return false - } - return true - } - controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .done)) - navigationController.setViewControllers(controllers, animated: true) + + switch strongSelf.engine { + case let .authorized(engine): + let _ = (engine.auth.updateTwoStepVerificationEmail(currentPassword: password, updatedEmail: text) + |> deliverOnMainQueue).start(next: { [weak statusController] result in + statusController?.dismiss() + + guard let strongSelf = self else { + return } - } - }, error: { [weak statusController] error in - statusController?.dismiss() - - guard let strongSelf = self else { - return - } - - let presentationData = strongSelf.presentationData - let alertText: String - switch error { - case .generic: - alertText = presentationData.strings.Login_UnknownError - case .invalidEmail: - alertText = presentationData.strings.TwoStepAuth_EmailInvalid - } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: alertText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - }) + + switch result { + case .none: + break + case let .password(_, pendingEmail): + if let pendingEmail = pendingEmail { + guard let navigationController = strongSelf.navigationController as? NavigationController else { + return + } + var controllers = navigationController.viewControllers.filter { controller in + if controller is TwoFactorAuthSplashScreen { + return false + } + if controller is TwoFactorDataInputScreen { + return false + } + return true + } + controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailConfirmation(passwordAndHint: (password, ""), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init)), stateUpdated: strongSelf.stateUpdated)) + navigationController.setViewControllers(controllers, animated: true) + } else { + guard let navigationController = strongSelf.navigationController as? NavigationController else { + return + } + var controllers = navigationController.viewControllers.filter { controller in + if controller is TwoFactorAuthSplashScreen { + return false + } + if controller is TwoFactorDataInputScreen { + return false + } + return true + } + controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done)) + navigationController.setViewControllers(controllers, animated: true) + } + } + }, error: { [weak statusController] error in + statusController?.dismiss() + + guard let strongSelf = self else { + return + } + + let presentationData = strongSelf.presentationData + let alertText: String + switch error { + case .generic: + alertText = presentationData.strings.Login_UnknownError + case .invalidEmail: + alertText = presentationData.strings.TwoStepAuth_EmailInvalid + } + strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: alertText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + }) + case .unauthorized: + break + } case .emailConfirmation: guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else { return } let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil)) strongSelf.present(statusController, in: .window(.root)) - - let _ = (confirmTwoStepRecoveryEmail(network: strongSelf.network, code: text) - |> deliverOnMainQueue).start(error: { [weak statusController] error in - statusController?.dismiss() - - guard let strongSelf = self else { - return - } - - let presentationData = strongSelf.presentationData - let text: String - switch error { - case .invalidEmail: - text = presentationData.strings.TwoStepAuth_EmailInvalid - case .invalidCode: - text = presentationData.strings.Login_InvalidCodeError - case .expired: - text = presentationData.strings.TwoStepAuth_EmailCodeExpired - case .flood: - text = presentationData.strings.TwoStepAuth_FloodError - case .generic: - text = presentationData.strings.Login_UnknownError - } - strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - }, completed: { [weak statusController] in - statusController?.dismiss() - - guard let strongSelf = self else { - return - } - - guard let navigationController = strongSelf.navigationController as? NavigationController else { - return - } - var controllers = navigationController.viewControllers.filter { controller in - if controller is TwoFactorAuthSplashScreen { - return false + + switch strongSelf.engine { + case let .authorized(engine): + let _ = (engine.auth.confirmTwoStepRecoveryEmail(code: text) + |> deliverOnMainQueue).start(error: { [weak statusController] error in + statusController?.dismiss() + + guard let strongSelf = self else { + return } - if controller is TwoFactorDataInputScreen { - return false + + let presentationData = strongSelf.presentationData + let text: String + switch error { + case .invalidEmail: + text = presentationData.strings.TwoStepAuth_EmailInvalid + case .invalidCode: + text = presentationData.strings.Login_InvalidCodeError + case .expired: + text = presentationData.strings.TwoStepAuth_EmailCodeExpired + case .flood: + text = presentationData.strings.TwoStepAuth_FloodError + case .generic: + text = presentationData.strings.Login_UnknownError } - return true - } - controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .done)) - navigationController.setViewControllers(controllers, animated: true) - }) + strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + }, completed: { [weak statusController] in + statusController?.dismiss() + + guard let strongSelf = self else { + return + } + + guard let navigationController = strongSelf.navigationController as? NavigationController else { + return + } + var controllers = navigationController.viewControllers.filter { controller in + if controller is TwoFactorAuthSplashScreen { + return false + } + if controller is TwoFactorDataInputScreen { + return false + } + return true + } + controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done)) + navigationController.setViewControllers(controllers, animated: true) + }) + case .unauthorized: + break + } case let .passwordHint(recovery, password): guard let value = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !value.isEmpty else { return @@ -327,7 +337,7 @@ public final class TwoFactorDataInputScreen: ViewController { if let recovery = recovery { strongSelf.performRecovery(recovery: recovery, password: password, hint: value) } else { - strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .emailAddress(password: password, hint: value), stateUpdated: strongSelf.stateUpdated)) + strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: value), stateUpdated: strongSelf.stateUpdated)) } } }, skipAction: { [weak self] in @@ -344,7 +354,7 @@ public final class TwoFactorDataInputScreen: ViewController { let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil)) strongSelf.present(statusController, in: .window(.root)) - let _ = (updateTwoStepVerificationPassword(network: strongSelf.network, currentPassword: "", updatedPassword: .password(password: password, hint: hint, email: nil)) + let _ = (strongSelf.engine.auth.updateTwoStepVerificationPassword(currentPassword: "", updatedPassword: .password(password: password, hint: hint, email: nil)) |> deliverOnMainQueue).start(next: { [weak statusController] result in statusController?.dismiss() @@ -368,7 +378,7 @@ public final class TwoFactorDataInputScreen: ViewController { } return true } - controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .done)) + controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done)) navigationController.setViewControllers(controllers, animated: true) } }, error: { [weak statusController] error in @@ -395,7 +405,7 @@ public final class TwoFactorDataInputScreen: ViewController { if let recovery = recovery { strongSelf.performRecovery(recovery: recovery, password: password, hint: "") } else { - strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .emailAddress(password: password, hint: ""), stateUpdated: strongSelf.stateUpdated)) + strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: ""), stateUpdated: strongSelf.stateUpdated)) } case let .passwordRecovery(recovery): strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertTitle, text: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertText, actions: [ @@ -429,7 +439,7 @@ public final class TwoFactorDataInputScreen: ViewController { } return true } - controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .emailAddress(password: password, hint: hint), stateUpdated: strongSelf.stateUpdated)) + controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: hint), stateUpdated: strongSelf.stateUpdated)) navigationController.setViewControllers(controllers, animated: true) } else { } @@ -443,8 +453,8 @@ public final class TwoFactorDataInputScreen: ViewController { let statusController = OverlayStatusController(theme: strongSelf.presentationData.theme, type: .loading(cancelled: nil)) strongSelf.present(statusController, in: .window(.root)) - - let _ = (resendTwoStepRecoveryEmail(network: strongSelf.network) + + let _ = (strongSelf.engine.auth.resendTwoStepRecoveryEmail() |> deliverOnMainQueue).start(error: { [weak statusController] error in statusController?.dismiss() @@ -475,10 +485,13 @@ public final class TwoFactorDataInputScreen: ViewController { } private func performRecovery(recovery: TwoFactorDataInputMode.Recovery, password: String, hint: String) { + guard case let .unauthorized(engine) = self.engine else { + return + } let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: nil)) self.present(statusController, in: .window(.root)) - let _ = (performPasswordRecovery(accountManager: self.sharedContext.accountManager, account: recovery.account, code: recovery.code, syncContacts: recovery.syncContacts, updatedPassword: password.isEmpty ? .none : .password(password: password, hint: hint, email: nil)) + let _ = (engine.auth.performPasswordRecovery(accountManager: self.sharedContext.accountManager, code: recovery.code, syncContacts: recovery.syncContacts, updatedPassword: password.isEmpty ? .none : .password(password: password, hint: hint, email: nil)) |> deliverOnMainQueue).start(error: { [weak self, weak statusController] error in statusController?.dismiss() diff --git a/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift b/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift index 8a2fe0f068..8f62595254 100644 --- a/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift +++ b/submodules/PasswordSetupUI/Sources/TwoFactorAuthSplashScreen.swift @@ -19,13 +19,13 @@ public enum TwoFactorAuthSplashMode { public final class TwoFactorAuthSplashScreen: ViewController { private let sharedContext: SharedAccountContext - private let network: Network + private let engine: SomeTelegramEngine private var presentationData: PresentationData private var mode: TwoFactorAuthSplashMode - public init(sharedContext: SharedAccountContext, network: Network, mode: TwoFactorAuthSplashMode) { + public init(sharedContext: SharedAccountContext, engine: SomeTelegramEngine, mode: TwoFactorAuthSplashMode) { self.sharedContext = sharedContext - self.network = network + self.engine = engine self.mode = mode self.presentationData = self.sharedContext.currentPresentationData.with { $0 } @@ -57,7 +57,7 @@ public final class TwoFactorAuthSplashScreen: ViewController { } switch strongSelf.mode { case .intro: - strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.network, mode: .password, stateUpdated: { _ in + strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password, stateUpdated: { _ in })) case .done: guard let navigationController = strongSelf.navigationController as? NavigationController else { diff --git a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift index 540cce7c68..c60aa3387d 100644 --- a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift @@ -779,7 +779,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina } let state = stateValue.with { $0 } if let modifiedSlowmodeTimeout = state.modifiedSlowmodeTimeout { - updateDefaultRightsDisposable.set(updateChannelSlowModeInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: view.peerId, timeout: modifiedSlowmodeTimeout == 0 ? nil : value).start()) + updateDefaultRightsDisposable.set(context.engine.peers.updateChannelSlowModeInteractively(peerId: view.peerId, timeout: modifiedSlowmodeTimeout == 0 ? nil : value).start()) } } else if let _ = view.peers[view.peerId] as? TelegramGroup, let _ = view.cachedData as? CachedGroupData { updateState { state in @@ -815,7 +815,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina } } |> mapToSignal { upgradedPeerId -> Signal in - return updateChannelSlowModeInteractively(postbox: context.account.postbox, network: context.account.network, accountStateManager: context.account.stateManager, peerId: upgradedPeerId, timeout: modifiedSlowmodeTimeout == 0 ? nil : value) + return context.engine.peers.updateChannelSlowModeInteractively(peerId: upgradedPeerId, timeout: modifiedSlowmodeTimeout == 0 ? nil : value) |> mapToSignal { _ -> Signal in return .complete() } diff --git a/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift b/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift deleted file mode 100644 index 70c6a25db9..0000000000 --- a/submodules/PeerInfoUI/Sources/GroupsInCommonController.swift +++ /dev/null @@ -1,244 +0,0 @@ -import Foundation -import UIKit -import AsyncDisplayKit -import Display -import SwiftSignalKit -import Postbox -import TelegramCore -import SyncCore -import TelegramPresentationData -import TelegramUIPreferences -import ItemListUI -import PresentationDataUtils -import AccountContext -import ItemListPeerItem -import ContextUI - -private final class GroupsInCommonControllerArguments { - let context: AccountContext - - let openPeer: (PeerId) -> Void - let contextAction: (Peer, ASDisplayNode, ContextGesture?) -> Void - - init(context: AccountContext, openPeer: @escaping (PeerId) -> Void, contextAction: @escaping (Peer, ASDisplayNode, ContextGesture?) -> Void) { - self.context = context - self.openPeer = openPeer - self.contextAction = contextAction - } -} - -private enum GroupsInCommonSection: Int32 { - case peers -} - -private enum GroupsInCommonEntryStableId: Hashable { - case peer(PeerId) -} - -private enum GroupsInCommonEntry: ItemListNodeEntry { - case peerItem(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, Peer) - - var section: ItemListSectionId { - switch self { - case .peerItem: - return GroupsInCommonSection.peers.rawValue - } - } - - var stableId: GroupsInCommonEntryStableId { - switch self { - case let .peerItem(_, _, _, _, _, peer): - return .peer(peer.id) - } - } - - static func ==(lhs: GroupsInCommonEntry, rhs: GroupsInCommonEntry) -> Bool { - switch lhs { - case let .peerItem(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsNameOrder, lhsPeer): - if case let .peerItem(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsNameOrder, rhsPeer) = rhs { - if lhsIndex != rhsIndex { - return false - } - if lhsTheme !== rhsTheme { - return false - } - if lhsStrings !== rhsStrings { - return false - } - if lhsDateTimeFormat != rhsDateTimeFormat { - return false - } - if !lhsPeer.isEqual(rhsPeer) { - return false - } - if lhsNameOrder != rhsNameOrder { - return false - } - return true - } else { - return false - } - } - } - - static func <(lhs: GroupsInCommonEntry, rhs: GroupsInCommonEntry) -> Bool { - switch lhs { - case let .peerItem(index, _, _, _, _, _): - switch rhs { - case let .peerItem(rhsIndex, _, _, _, _, _): - return index < rhsIndex - } - } - } - - func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { - let arguments = arguments as! GroupsInCommonControllerArguments - switch self { - case let .peerItem(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer): - return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: .none, label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: { - arguments.openPeer(peer.id) - }, setPeerIdWithRevealedOptions: { _, _ in - }, removePeer: { _ in - }, contextAction: { node, gesture in - arguments.contextAction(peer, node, gesture) - }) - } - } -} - -private struct GroupsInCommonControllerState: Equatable { - static func ==(lhs: GroupsInCommonControllerState, rhs: GroupsInCommonControllerState) -> Bool { - return true - } -} - -private func groupsInCommonControllerEntries(presentationData: PresentationData, state: GroupsInCommonControllerState, peers: [Peer]?) -> [GroupsInCommonEntry] { - var entries: [GroupsInCommonEntry] = [] - - if let peers = peers { - var index: Int32 = 0 - for peer in peers { - entries.append(.peerItem(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, peer)) - index += 1 - } - } - - return entries -} - -public func groupsInCommonController(context: AccountContext, peerId: PeerId) -> ViewController { - let statePromise = ValuePromise(GroupsInCommonControllerState(), ignoreRepeated: true) - let stateValue = Atomic(value: GroupsInCommonControllerState()) - let updateState: ((GroupsInCommonControllerState) -> GroupsInCommonControllerState) -> Void = { f in - statePromise.set(stateValue.modify { f($0) }) - } - - let actionsDisposable = DisposableSet() - - let peersPromise = Promise<[Peer]?>(nil) - - var pushControllerImpl: ((ViewController) -> Void)? - var getNavigationControllerImpl: (() -> NavigationController?)? - - var contextActionImpl: ((Peer, ASDisplayNode, ContextGesture?) -> Void)? - - let arguments = GroupsInCommonControllerArguments(context: context, openPeer: { memberId in - guard let navigationController = getNavigationControllerImpl?() else { - return - } - context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(memberId), animated: true)) - }, contextAction: { peer, node, gesture in - contextActionImpl?(peer, node, gesture) - }) - - let peersSignal: Signal<[Peer]?, NoError> = .single(nil) |> then(groupsInCommon(account: context.account, peerId: peerId) |> mapToSignal { peerIds -> Signal<[Peer], NoError> in - return context.account.postbox.transaction { transaction -> [Peer] in - var result: [Peer] = [] - for id in peerIds { - if let peer = transaction.getPeer(id.id) { - result.append(peer) - } - } - return result - } - } - |> map(Optional.init)) - - peersPromise.set(peersSignal) - - var previousPeers: [Peer]? - - let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), peersPromise.get()) - |> deliverOnMainQueue - |> map { presentationData, state, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in - var emptyStateItem: ItemListControllerEmptyStateItem? - if peers == nil { - emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) - } - - let previous = previousPeers - previousPeers = peers - - let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.UserInfo_GroupsInCommon), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: groupsInCommonControllerEntries(presentationData: presentationData, state: state, peers: peers), style: .blocks, emptyStateItem: emptyStateItem, animateChanges: previous != nil && peers != nil && previous!.count >= peers!.count) - - return (controllerState, (listState, arguments)) - } |> afterDisposed { - actionsDisposable.dispose() - } - - let controller = ItemListController(context: context, state: signal) - pushControllerImpl = { [weak controller] c in - if let controller = controller { - (controller.navigationController as? NavigationController)?.pushViewController(c) - } - } - getNavigationControllerImpl = { [weak controller] in - return controller?.navigationController as? NavigationController - } - contextActionImpl = { [weak controller] peer, node, gesture in - guard let controller = controller else { - return - } - let presentationData = context.sharedContext.currentPresentationData.with { $0 } - let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true)) - chatController.canReadHistory.set(false) - let items: [ContextMenuItem] = [ - .action(ContextMenuActionItem(text: presentationData.strings.Conversation_LinkDialogOpen, icon: { _ in nil }, action: { _, f in - f(.dismissWithoutContent) - arguments.openPeer(peer.id) - })) - ] - let contextController = ContextController(account: context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: .single(items), reactionItems: [], gesture: gesture) - controller.presentInGlobalOverlay(contextController) - } - return controller -} - -private final class ContextControllerContentSourceImpl: ContextControllerContentSource { - let controller: ViewController - weak var sourceNode: ASDisplayNode? - - let navigationController: NavigationController? = nil - - let passthroughTouches: Bool = true - - init(controller: ViewController, sourceNode: ASDisplayNode?) { - self.controller = controller - self.sourceNode = sourceNode - } - - func transitionInfo() -> ContextControllerTakeControllerInfo? { - let sourceNode = self.sourceNode - return ContextControllerTakeControllerInfo(contentAreaInScreenSpace: CGRect(origin: CGPoint(), size: CGSize(width: 10.0, height: 10.0)), sourceNode: { [weak sourceNode] in - if let sourceNode = sourceNode { - return (sourceNode, sourceNode.bounds) - } else { - return nil - } - }) - } - - func animatedIn() { - } -} diff --git a/submodules/PeerInfoUI/Sources/PeerReportController.swift b/submodules/PeerInfoUI/Sources/PeerReportController.swift index 0b7d57f71f..d13701fb43 100644 --- a/submodules/PeerInfoUI/Sources/PeerReportController.swift +++ b/submodules/PeerInfoUI/Sources/PeerReportController.swift @@ -107,19 +107,19 @@ public func presentPeerReportOptions(context: AccountContext, parent: ViewContro } else { switch subject { case let .peer(peerId): - let _ = (reportPeer(account: context.account, peerId: peerId, reason: reportReason, message: "") + let _ = (context.engine.peers.reportPeer(peerId: peerId, reason: reportReason, message: "") |> deliverOnMainQueue).start(completed: { displaySuccess() completion(nil, false) }) case let .messages(messageIds): - let _ = (reportPeerMessages(account: context.account, messageIds: messageIds, reason: reportReason, message: "") + let _ = (context.engine.peers.reportPeerMessages(messageIds: messageIds, reason: reportReason, message: "") |> deliverOnMainQueue).start(completed: { displaySuccess() completion(nil, false) }) case let .profilePhoto(peerId, photoId): - let _ = (reportPeerPhoto(account: context.account, peerId: peerId, reason: reportReason, message: "") + let _ = (context.engine.peers.reportPeerPhoto(peerId: peerId, reason: reportReason, message: "") |> deliverOnMainQueue).start(completed: { displaySuccess() completion(nil, false) @@ -233,19 +233,19 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe } else { switch subject { case let .peer(peerId): - let _ = (reportPeer(account: context.account, peerId: peerId, reason: reportReason, message: message) + let _ = (context.engine.peers.reportPeer(peerId: peerId, reason: reportReason, message: message) |> deliverOnMainQueue).start(completed: { displaySuccess() completion(nil, true) }) case let .messages(messageIds): - let _ = (reportPeerMessages(account: context.account, messageIds: messageIds, reason: reportReason, message: message) + let _ = (context.engine.peers.reportPeerMessages(messageIds: messageIds, reason: reportReason, message: message) |> deliverOnMainQueue).start(completed: { displaySuccess() completion(nil, true) }) case let .profilePhoto(peerId, photoId): - let _ = (reportPeerPhoto(account: context.account, peerId: peerId, reason: reportReason, message: message) + let _ = (context.engine.peers.reportPeerPhoto(peerId: peerId, reason: reportReason, message: message) |> deliverOnMainQueue).start(completed: { displaySuccess() completion(nil, true) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift b/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift index 5be4d7c79c..f8d3dc0936 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/CreatePasswordController.swift @@ -274,7 +274,7 @@ func createPasswordController(context: AccountContext, createPasswordContext: Cr state.saving = true return state } - saveDisposable.set((updateTwoStepVerificationPassword(network: context.account.network, currentPassword: currentPassword, updatedPassword: .password(password: state.passwordText, hint: state.hintText, email: email)) + saveDisposable.set((context.engine.auth.updateTwoStepVerificationPassword(currentPassword: currentPassword, updatedPassword: .password(password: state.passwordText, hint: state.hintText, email: email)) |> deliverOnMainQueue).start(next: { update in switch update { case .none: @@ -356,7 +356,7 @@ func createPasswordController(context: AccountContext, createPasswordContext: Cr return state } - saveDisposable.set((updateTwoStepVerificationPassword(network: context.account.network, currentPassword: currentPassword, updatedPassword: .none) + saveDisposable.set((context.engine.auth.updateTwoStepVerificationPassword(currentPassword: currentPassword, updatedPassword: .none) |> deliverOnMainQueue).start(next: { _ in updateState { state in var state = state diff --git a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift index 86596d241a..7f2ada099e 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/PrivacyAndSecurityController.swift @@ -542,7 +542,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting } let updateHasTwoStepAuth: () -> Void = { - let signal = twoStepVerificationConfiguration(account: context.account) + let signal = context.engine.auth.twoStepVerificationConfiguration() |> map { value -> TwoStepVerificationAccessConfiguration? in return TwoStepVerificationAccessConfiguration(configuration: value, password: nil) } @@ -735,7 +735,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting case let .notSet(pendingEmail): //intro = pendingEmail == nil if pendingEmail == nil { - let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, network: context.account.network, mode: .intro) + let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .intro) pushControllerImpl?(controller, true) return } else { diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift index 6a4ab372c1..b71f124495 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationPasswordEntryController.swift @@ -332,7 +332,7 @@ func twoStepVerificationPasswordEntryController(context: AccountContext, mode: T if case let .change(current) = mode { currentPassword = current } - updatePasswordDisposable.set((updateTwoStepVerificationPassword(network: context.account.network, currentPassword: currentPassword, updatedPassword: .password(password: password, hint: hint, email: email)) |> deliverOnMainQueue).start(next: { update in + updatePasswordDisposable.set((context.engine.auth.updateTwoStepVerificationPassword(currentPassword: currentPassword, updatedPassword: .password(password: password, hint: hint, email: email)) |> deliverOnMainQueue).start(next: { update in updateState { $0.withUpdatedUpdating(false) } @@ -357,7 +357,7 @@ func twoStepVerificationPasswordEntryController(context: AccountContext, mode: T presentControllerImpl?(textAlertController(context: context, title: nil, text: alertText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) })) case let .setupEmail(password): - updatePasswordDisposable.set((updateTwoStepVerificationEmail(network: context.account.network, currentPassword: password, updatedEmail: email) |> deliverOnMainQueue).start(next: { update in + updatePasswordDisposable.set((context.engine.auth.updateTwoStepVerificationEmail(currentPassword: password, updatedEmail: email) |> deliverOnMainQueue).start(next: { update in updateState { $0.withUpdatedUpdating(false) } diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift index acbd02cbe2..e5e271efb4 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationResetController.swift @@ -168,7 +168,7 @@ func twoStepVerificationResetController(context: AccountContext, emailPattern: S } } if let code = code { - resetPasswordDisposable.set((recoverTwoStepVerificationPassword(network: context.account.network, code: code) |> deliverOnMainQueue).start(error: { error in + resetPasswordDisposable.set((context.engine.auth.recoverTwoStepVerificationPassword(code: code) |> deliverOnMainQueue).start(error: { error in updateState { return $0.withUpdatedChecking(false) } @@ -204,7 +204,7 @@ func twoStepVerificationResetController(context: AccountContext, emailPattern: S let presentationData = context.sharedContext.currentPresentationData.with { $0 } presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetTitle, text: presentationData.strings.TwoStepAuth_RecoveryEmailResetText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetAction, action: { - let _ = (requestTwoStepPasswordReset(network: context.account.network) + let _ = (context.engine.auth.requestTwoStepPasswordReset() |> deliverOnMainQueue).start(next: { result in switch result { case .done, .waitingForReset: diff --git a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift index 33c4fa6996..727eff38c6 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/TwoStepVerificationUnlockController.swift @@ -316,7 +316,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: } else { dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: nil)) |> then(remoteDataPromise.get())) - remoteDataPromise.set(twoStepVerificationConfiguration(account: context.account) + remoteDataPromise.set(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) }) } case let .manage(password, email, pendingEmail, hasSecureValues): @@ -355,7 +355,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: return state } if let code = code { - setupDisposable.set((confirmTwoStepRecoveryEmail(network: context.account.network, code: code) + setupDisposable.set((context.engine.auth.confirmTwoStepRecoveryEmail(code: code) |> deliverOnMainQueue).start(error: { error in updateState { state in var state = state @@ -404,7 +404,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.manage(password: password, emailSet: true, pendingEmail: nil, hasSecureValues: false))) } else { dataPromise.set(.single(.access(configuration: nil)) - |> then(twoStepVerificationConfiguration(account: context.account) |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: pendingEmail.password)) })) + |> then(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: pendingEmail.password)) })) } case let .manage(manage): dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.manage(password: manage.password, emailSet: true, pendingEmail: nil, hasSecureValues: manage.hasSecureValues))) @@ -441,9 +441,9 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: } if let password = password, !password.isEmpty, !wasChecking { - checkDisposable.set((requestTwoStepVerifiationSettings(network: context.account.network, password: password) + checkDisposable.set((context.engine.auth.requestTwoStepVerifiationSettings(password: password) |> mapToSignal { settings -> Signal<(TwoStepVerificationSettings, TwoStepVerificationPendingEmail?), AuthorizationPasswordVerificationError> in - return twoStepVerificationConfiguration(account: context.account) + return context.engine.auth.twoStepVerificationConfiguration() |> mapError { _ -> AuthorizationPasswordVerificationError in } |> map { configuration in @@ -500,7 +500,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: state.checking = true return state } - setupResultDisposable.set((requestTwoStepVerificationPasswordRecoveryCode(network: context.account.network) + setupResultDisposable.set((context.engine.auth.requestTwoStepVerificationPasswordRecoveryCode() |> deliverOnMainQueue).start(next: { emailPattern in updateState { state in var state = state @@ -514,7 +514,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: }) completionImpl = { [weak controller] result in if !result { - dataPromise.set(twoStepVerificationConfiguration(account: context.account) + dataPromise.set(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) }) controller?.view.endEditing(true) @@ -541,11 +541,11 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: if let pendingResetTimestamp = pendingResetTimestamp { let remainingSeconds = pendingResetTimestamp - Int32(Date().timeIntervalSince1970) if remainingSeconds <= 0 { - let _ = (requestTwoStepPasswordReset(network: context.account.network) + let _ = (context.engine.auth.requestTwoStepPasswordReset() |> deliverOnMainQueue).start(next: { result in switch result { case .done, .waitingForReset: - dataPromise.set(twoStepVerificationConfiguration(account: context.account) + dataPromise.set(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) }) case .declined: @@ -557,11 +557,11 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: } } else { presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetTitle, text: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetAction, action: { - let _ = (requestTwoStepPasswordReset(network: context.account.network) + let _ = (context.engine.auth.requestTwoStepPasswordReset() |> deliverOnMainQueue).start(next: { result in switch result { case .done, .waitingForReset: - dataPromise.set(twoStepVerificationConfiguration(account: context.account) + dataPromise.set(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) }) case .declined: @@ -603,7 +603,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.TwoStepAuth_EnabledSuccess, false)), nil) } else { dataPromise.set(.single(.access(configuration: nil)) - |> then(twoStepVerificationConfiguration(account: context.account) |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) + |> then(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) } } if shouldDismiss { @@ -635,7 +635,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.TwoStepAuth_PasswordChangeSuccess, false)), nil) } else { dataPromise.set(.single(.access(configuration: nil)) - |> then(twoStepVerificationConfiguration(account: context.account) |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) + |> then(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) } } if shouldDismiss { @@ -677,7 +677,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: case let .manage(password, _, _, _): let presentationData = context.sharedContext.currentPresentationData.with { $0 } presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.TwoStepAuth_DisableSuccess, false)), nil) - return updateTwoStepVerificationPassword(network: context.account.network, currentPassword: password, updatedPassword: .none) + return context.engine.auth.updateTwoStepVerificationPassword(currentPassword: password, updatedPassword: .none) |> mapToSignal { _ -> Signal in return .complete() } @@ -730,7 +730,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(emailSet ? presentationData.strings.TwoStepAuth_EmailChangeSuccess : presentationData.strings.TwoStepAuth_EmailAddSuccess, false)), nil) } else { dataPromise.set(.single(.access(configuration: nil)) - |> then(twoStepVerificationConfiguration(account: context.account) |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) + |> then(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) } } if shouldDismiss { @@ -746,7 +746,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: state.checking = true return state } - setupDisposable.set((updateTwoStepVerificationPassword(network: context.account.network, currentPassword: nil, updatedPassword: .none) + setupDisposable.set((context.engine.auth.updateTwoStepVerificationPassword(currentPassword: nil, updatedPassword: .none) |> deliverOnMainQueue).start(next: { _ in updateState { state in var state = state @@ -817,7 +817,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: dataPromise.set(.single(data)) } else { dataPromise.set(.single(.access(configuration: nil)) - |> then(twoStepVerificationConfiguration(account: context.account) |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) + |> then(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: password)) })) } } if shouldDismiss { @@ -830,22 +830,22 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode: }, declinePasswordReset: { let presentationData = context.sharedContext.currentPresentationData.with { $0 } presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_CancelResetTitle, text: presentationData.strings.TwoStepAuth_CancelResetText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Yes, action: { - let _ = (declineTwoStepPasswordReset(network: context.account.network) + let _ = (context.engine.auth.declineTwoStepPasswordReset() |> deliverOnMainQueue).start(completed: { - dataPromise.set(twoStepVerificationConfiguration(account: context.account) + dataPromise.set(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) }) }) }), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_No, action: { })]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet)) }, resetPassword: { - let _ = (requestTwoStepPasswordReset(network: context.account.network) + let _ = (context.engine.auth.requestTwoStepPasswordReset() |> deliverOnMainQueue).start(next: { result in switch result { case .done: dismissImpl?() case .waitingForReset: - dataPromise.set(twoStepVerificationConfiguration(account: context.account) + dataPromise.set(context.engine.auth.twoStepVerificationConfiguration() |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) }) case .declined: diff --git a/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift b/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift index 3016ce0f12..d21e7b7cd1 100644 --- a/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift +++ b/submodules/TelegramCallsUI/Sources/CallFeedbackController.swift @@ -314,7 +314,7 @@ public func callFeedbackController(sharedContext: SharedAccountContext, account: } comment.append(hashtags) - let _ = rateCallAndSendLogs(account: account, callId: callId, starsCount: rating, comment: comment, userInitiated: userInitiated, includeLogs: state.includeLogs).start() + let _ = rateCallAndSendLogs(engine: TelegramEngine(account: account), callId: callId, starsCount: rating, comment: comment, userInitiated: userInitiated, includeLogs: state.includeLogs).start() dismissImpl?() presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .starSuccess(presentationData.strings.CallFeedback_Success))) diff --git a/submodules/TelegramCallsUI/Sources/CallRatingController.swift b/submodules/TelegramCallsUI/Sources/CallRatingController.swift index 72ce0d4316..961f02c7a6 100644 --- a/submodules/TelegramCallsUI/Sources/CallRatingController.swift +++ b/submodules/TelegramCallsUI/Sources/CallRatingController.swift @@ -240,24 +240,24 @@ private final class CallRatingAlertContentNode: AlertContentNode { } } -func rateCallAndSendLogs(account: Account, callId: CallId, starsCount: Int, comment: String, userInitiated: Bool, includeLogs: Bool) -> Signal { +func rateCallAndSendLogs(engine: TelegramEngine, callId: CallId, starsCount: Int, comment: String, userInitiated: Bool, includeLogs: Bool) -> Signal { let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt32Value(4244000)) - let rate = rateCall(account: account, callId: callId, starsCount: Int32(starsCount), comment: comment, userInitiated: userInitiated) + let rate = engine.calls.rateCall(callId: callId, starsCount: Int32(starsCount), comment: comment, userInitiated: userInitiated) if includeLogs { let id = Int64.random(in: Int64.min ... Int64.max) let name = "\(callId.id)_\(callId.accessHash).log.json" - let path = callLogsPath(account: account) + "/" + name + let path = callLogsPath(account: engine.account) + "/" + name let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: LocalFileReferenceMediaResource(localFilePath: path, randomId: id), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: nil, attributes: [.FileName(fileName: name)]) let message = EnqueueMessage.message(text: comment, attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil) return rate - |> then(enqueueMessages(account: account, peerId: peerId, messages: [message]) + |> then(enqueueMessages(account: engine.account, peerId: peerId, messages: [message]) |> mapToSignal({ _ -> Signal in return .single(Void()) })) } else if !comment.isEmpty { return rate - |> then(enqueueMessages(account: account, peerId: peerId, messages: [.message(text: comment, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]) + |> then(enqueueMessages(account: engine.account, peerId: peerId, messages: [.message(text: comment, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]) |> mapToSignal({ _ -> Signal in return .single(Void()) })) @@ -284,7 +284,7 @@ public func callRatingController(sharedContext: SharedAccountContext, account: A if rating < 4 { push(callFeedbackController(sharedContext: sharedContext, account: account, callId: callId, rating: rating, userInitiated: userInitiated, isVideo: isVideo)) } else { - let _ = rateCallAndSendLogs(account: account, callId: callId, starsCount: rating, comment: "", userInitiated: userInitiated, includeLogs: false).start() + let _ = rateCallAndSendLogs(engine: TelegramEngine(account: account), callId: callId, starsCount: rating, comment: "", userInitiated: userInitiated, includeLogs: false).start() } }) diff --git a/submodules/TelegramCore/Sources/Account.swift b/submodules/TelegramCore/Sources/Account.swift index 808361feb3..60a3bb4429 100644 --- a/submodules/TelegramCore/Sources/Account.swift +++ b/submodules/TelegramCore/Sources/Account.swift @@ -373,7 +373,7 @@ public struct TwoStepAuthData { public let pendingResetTimestamp: Int32? } -public func twoStepAuthData(_ network: Network) -> Signal { +func _internal_twoStepAuthData(_ network: Network) -> Signal { return network.request(Api.functions.account.getPassword()) |> map { config -> TwoStepAuthData in switch config { @@ -664,7 +664,7 @@ func securePasswordKDF(password: String, derivation: TwoStepSecurePasswordDeriva } func verifyPassword(_ account: UnauthorizedAccount, password: String) -> Signal { - return twoStepAuthData(account.network) + return _internal_twoStepAuthData(account.network) |> mapToSignal { authData -> Signal in guard let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData else { return .fail(MTRpcError(errorCode: 400, errorDescription: "INTERNAL_NO_PASSWORD")) diff --git a/submodules/TelegramCore/Sources/Authorization.swift b/submodules/TelegramCore/Sources/Authorization.swift index ccc03759c8..ef1acec2b7 100644 --- a/submodules/TelegramCore/Sources/Authorization.swift +++ b/submodules/TelegramCore/Sources/Authorization.swift @@ -389,8 +389,8 @@ public func checkPasswordRecoveryCode(network: Network, code: String) -> Signal< } } -public func performPasswordRecovery(accountManager: AccountManager, account: UnauthorizedAccount, code: String, syncContacts: Bool, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { - return twoStepAuthData(account.network) +func _internal_performPasswordRecovery(accountManager: AccountManager, account: UnauthorizedAccount, code: String, syncContacts: Bool, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { + return _internal_twoStepAuthData(account.network) |> mapError { _ -> PasswordRecoveryError in return .generic } diff --git a/submodules/TelegramCore/Sources/ChannelOwnershipTransfer.swift b/submodules/TelegramCore/Sources/ChannelOwnershipTransfer.swift index 976766c460..a79b0a2a56 100644 --- a/submodules/TelegramCore/Sources/ChannelOwnershipTransfer.swift +++ b/submodules/TelegramCore/Sources/ChannelOwnershipTransfer.swift @@ -95,7 +95,7 @@ public func updateChannelOwnership(account: Account, accountStateManager: Accoun let updatedParticipant = ChannelParticipant.creator(id: user.id, adminInfo: nil, rank: currentParticipant?.rank) let updatedPreviousCreator = ChannelParticipant.member(id: accountUser.id, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: flags), promotedBy: accountUser.id, canBeEditedByAccountPeer: false), banInfo: nil, rank: currentCreator?.rank) - let checkPassword = twoStepAuthData(account.network) + let checkPassword = _internal_twoStepAuthData(account.network) |> mapError { error -> ChannelOwnershipTransferError in if error.errorDescription.hasPrefix("FLOOD_WAIT") { return .limitExceeded diff --git a/submodules/TelegramCore/Sources/ChatHistoryImport.swift b/submodules/TelegramCore/Sources/ChatHistoryImport.swift deleted file mode 100644 index d1e5811512..0000000000 --- a/submodules/TelegramCore/Sources/ChatHistoryImport.swift +++ /dev/null @@ -1,244 +0,0 @@ -import Foundation -import SwiftSignalKit -import Postbox -import SyncCore -import TelegramApi - -public enum ChatHistoryImport { - public struct Session { - fileprivate var peerId: PeerId - fileprivate var inputPeer: Api.InputPeer - fileprivate var id: Int64 - } - - public enum InitImportError { - case generic - case chatAdminRequired - case invalidChatType - case userBlocked - case limitExceeded - } - - public enum ParsedInfo { - case privateChat(title: String?) - case group(title: String?) - case unknown(title: String?) - } - - public enum GetInfoError { - case generic - case parseError - } - - public static func getInfo(account: Account, header: String) -> Signal { - return account.network.request(Api.functions.messages.checkHistoryImport(importHead: header)) - |> mapError { _ -> GetInfoError in - return .generic - } - |> mapToSignal { result -> Signal in - switch result { - case let .historyImportParsed(flags, title): - if (flags & (1 << 0)) != 0 { - return .single(.privateChat(title: title)) - } else if (flags & (1 << 1)) != 0 { - return .single(.group(title: title)) - } else { - return .single(.unknown(title: title)) - } - } - } - } - - public static func initSession(account: Account, peerId: PeerId, file: TempBoxFile, mediaCount: Int32) -> Signal { - return multipartUpload(network: account.network, postbox: account.postbox, source: .tempFile(file), encrypt: false, tag: nil, hintFileSize: nil, hintFileIsLarge: false, forceNoBigParts: true, useLargerParts: true, increaseParallelParts: true, useMultiplexedRequests: false, useCompression: true) - |> mapError { _ -> InitImportError in - return .generic - } - |> mapToSignal { result -> Signal in - switch result { - case let .inputFile(inputFile): - return account.postbox.transaction { transaction -> Api.InputPeer? in - return transaction.getPeer(peerId).flatMap(apiInputPeer) - } - |> castError(InitImportError.self) - |> mapToSignal { inputPeer -> Signal in - guard let inputPeer = inputPeer else { - return .fail(.generic) - } - return account.network.request(Api.functions.messages.initHistoryImport(peer: inputPeer, file: inputFile, mediaCount: mediaCount), automaticFloodWait: false) - |> mapError { error -> InitImportError in - if error.errorDescription == "CHAT_ADMIN_REQUIRED" { - return .chatAdminRequired - } else if error.errorDescription == "IMPORT_PEER_TYPE_INVALID" { - return .invalidChatType - } else if error.errorDescription == "USER_IS_BLOCKED" { - return .userBlocked - } else if error.errorDescription == "FLOOD_WAIT" { - return .limitExceeded - } else { - return .generic - } - } - |> map { result -> Session in - switch result { - case let .historyImport(id): - return Session(peerId: peerId, inputPeer: inputPeer, id: id) - } - } - } - case .progress: - return .complete() - case .inputSecretFile: - return .fail(.generic) - } - } - } - - public enum MediaType { - case photo - case file - case video - case sticker - case voice - } - - public enum UploadMediaError { - case generic - case chatAdminRequired - } - - public static func uploadMedia(account: Account, session: Session, file: TempBoxFile, disposeFileAfterDone: Bool, fileName: String, mimeType: String, type: MediaType) -> Signal { - var forceNoBigParts = true - guard let size = fileSize(file.path), size != 0 else { - return .single(1.0) - } - if size >= 30 * 1024 * 1024 { - forceNoBigParts = false - } - - return multipartUpload(network: account.network, postbox: account.postbox, source: .tempFile(file), encrypt: false, tag: nil, hintFileSize: nil, hintFileIsLarge: false, forceNoBigParts: forceNoBigParts, useLargerParts: true, useMultiplexedRequests: true) - |> mapError { _ -> UploadMediaError in - return .generic - } - |> mapToSignal { result -> Signal in - let inputMedia: Api.InputMedia - switch result { - case let .inputFile(inputFile): - switch type { - case .photo: - inputMedia = .inputMediaUploadedPhoto(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil) - case .file, .video, .sticker, .voice: - var attributes: [Api.DocumentAttribute] = [] - attributes.append(.documentAttributeFilename(fileName: fileName)) - var resolvedMimeType = mimeType - switch type { - case .video: - resolvedMimeType = "video/mp4" - case .sticker: - resolvedMimeType = "image/webp" - case .voice: - resolvedMimeType = "audio/ogg" - default: - break - } - inputMedia = .inputMediaUploadedDocument(flags: 0, file: inputFile, thumb: nil, mimeType: resolvedMimeType, attributes: attributes, stickers: nil, ttlSeconds: nil) - } - case let .progress(value): - return .single(value) - case .inputSecretFile: - return .fail(.generic) - } - return account.network.request(Api.functions.messages.uploadImportedMedia(peer: session.inputPeer, importId: session.id, fileName: fileName, media: inputMedia)) - |> mapError { error -> UploadMediaError in - switch error.errorDescription { - case "CHAT_ADMIN_REQUIRED": - return .chatAdminRequired - default: - return .generic - } - } - |> mapToSignal { result -> Signal in - return .single(1.0) - } - |> afterDisposed { - if disposeFileAfterDone { - TempBox.shared.dispose(file) - } - } - } - } - - public enum StartImportError { - case generic - } - - public static func startImport(account: Account, session: Session) -> Signal { - return account.network.request(Api.functions.messages.startHistoryImport(peer: session.inputPeer, importId: session.id)) - |> mapError { _ -> StartImportError in - return .generic - } - |> mapToSignal { result -> Signal in - if case .boolTrue = result { - return .complete() - } else { - return .fail(.generic) - } - } - } - - public enum CheckPeerImportResult { - case allowed - case alert(String) - } - - public enum CheckPeerImportError { - case generic - case chatAdminRequired - case invalidChatType - case userBlocked - case limitExceeded - case notMutualContact - } - - public static func checkPeerImport(account: Account, peerId: PeerId) -> Signal { - return account.postbox.transaction { transaction -> Peer? in - return transaction.getPeer(peerId) - } - |> castError(CheckPeerImportError.self) - |> mapToSignal { peer -> Signal in - guard let peer = peer else { - return .fail(.generic) - } - guard let inputPeer = apiInputPeer(peer) else { - return .fail(.generic) - } - - return account.network.request(Api.functions.messages.checkHistoryImportPeer(peer: inputPeer)) - |> mapError { error -> CheckPeerImportError in - if error.errorDescription == "CHAT_ADMIN_REQUIRED" { - return .chatAdminRequired - } else if error.errorDescription == "IMPORT_PEER_TYPE_INVALID" { - return .invalidChatType - } else if error.errorDescription == "USER_IS_BLOCKED" { - return .userBlocked - } else if error.errorDescription == "USER_NOT_MUTUAL_CONTACT" { - return .notMutualContact - } else if error.errorDescription == "FLOOD_WAIT" { - return .limitExceeded - } else { - return .generic - } - } - |> map { result -> CheckPeerImportResult in - switch result { - case let .checkedHistoryImportPeer(confirmText): - if confirmText.isEmpty { - return .allowed - } else { - return .alert(confirmText) - } - } - } - } - } -} diff --git a/submodules/TelegramCore/Sources/GlobalTelegramCoreConfiguration.swift b/submodules/TelegramCore/Sources/GlobalTelegramCoreConfiguration.swift deleted file mode 100644 index 7cf05d8aa9..0000000000 --- a/submodules/TelegramCore/Sources/GlobalTelegramCoreConfiguration.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Foundation - -public final class GlobalTelegramCoreConfiguration { - public static var readMessages: Bool = true -} diff --git a/submodules/TelegramCore/Sources/SetSecretChatMessageAutoremoveTimeoutInteractively.swift b/submodules/TelegramCore/Sources/SecretChats/SetSecretChatMessageAutoremoveTimeoutInteractively.swift similarity index 88% rename from submodules/TelegramCore/Sources/SetSecretChatMessageAutoremoveTimeoutInteractively.swift rename to submodules/TelegramCore/Sources/SecretChats/SetSecretChatMessageAutoremoveTimeoutInteractively.swift index 13906bc270..8dba9e3b3c 100644 --- a/submodules/TelegramCore/Sources/SetSecretChatMessageAutoremoveTimeoutInteractively.swift +++ b/submodules/TelegramCore/Sources/SecretChats/SetSecretChatMessageAutoremoveTimeoutInteractively.swift @@ -4,7 +4,7 @@ import SwiftSignalKit import SyncCore -public func setSecretChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?) -> Signal { +func _internal_setSecretChatMessageAutoremoveTimeoutInteractively(account: Account, peerId: PeerId, timeout: Int32?) -> Signal { return account.postbox.transaction { transaction -> Void in if let peer = transaction.getPeer(peerId) as? TelegramSecretChat, let state = transaction.getPeerChatState(peerId) as? SecretChatState { if state.messageAutoremoveTimeout != timeout { @@ -23,7 +23,7 @@ public func setSecretChatMessageAutoremoveTimeoutInteractively(account: Account, } } -public func addSecretChatMessageScreenshot(account: Account, peerId: PeerId) -> Signal { +func _internal_addSecretChatMessageScreenshot(account: Account, peerId: PeerId) -> Signal { return account.postbox.transaction { transaction -> Void in if let _ = transaction.getPeer(peerId) as? TelegramSecretChat, let state = transaction.getPeerChatState(peerId) as? SecretChatState { switch state.embeddedState { diff --git a/submodules/TelegramCore/Sources/State/CallSessionManager.swift b/submodules/TelegramCore/Sources/State/CallSessionManager.swift index afd27413f2..7d6cdfde5a 100644 --- a/submodules/TelegramCore/Sources/State/CallSessionManager.swift +++ b/submodules/TelegramCore/Sources/State/CallSessionManager.swift @@ -563,7 +563,7 @@ private final class CallSessionManagerContext { |> timeout(5.0, queue: strongSelf.queue, alternate: .single(nil)) |> deliverOnMainQueue).start(next: { debugLog in if let debugLog = debugLog { - let _ = saveCallDebugLog(network: network, callId: CallId(id: id, accessHash: accessHash), log: debugLog).start() + _internal_saveCallDebugLog(network: network, callId: CallId(id: id, accessHash: accessHash), log: debugLog).start() } }) } diff --git a/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift b/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift index 6d745cb599..46d81f30be 100644 --- a/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift +++ b/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift @@ -206,10 +206,6 @@ private func validatePeerReadState(network: Network, postbox: Postbox, stateMana } private func pushPeerReadState(network: Network, postbox: Postbox, stateManager: AccountStateManager, peerId: PeerId, readState: PeerReadState) -> Signal { - if !GlobalTelegramCoreConfiguration.readMessages { - return .single(readState) - } - if peerId.namespace == Namespaces.Peer.SecretChat { return inputSecretChat(postbox: postbox, peerId: peerId) |> mapToSignal { inputPeer -> Signal in diff --git a/submodules/TelegramCore/Sources/ConfirmTwoStepRecoveryEmail.swift b/submodules/TelegramCore/Sources/TelegramEngine/Auth/ConfirmTwoStepRecoveryEmail.swift similarity index 80% rename from submodules/TelegramCore/Sources/ConfirmTwoStepRecoveryEmail.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Auth/ConfirmTwoStepRecoveryEmail.swift index dcc5c4433f..240ae7f8a0 100644 --- a/submodules/TelegramCore/Sources/ConfirmTwoStepRecoveryEmail.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Auth/ConfirmTwoStepRecoveryEmail.swift @@ -12,7 +12,7 @@ public enum ConfirmTwoStepRecoveryEmailError { case generic } -public func confirmTwoStepRecoveryEmail(network: Network, code: String) -> Signal { +func _internal_confirmTwoStepRecoveryEmail(network: Network, code: String) -> Signal { return network.request(Api.functions.account.confirmPasswordEmail(code: code), automaticFloodWait: false) |> mapError { error -> ConfirmTwoStepRecoveryEmailError in if error.errorDescription == "EMAIL_INVALID" { @@ -34,7 +34,7 @@ public enum ResendTwoStepRecoveryEmailError { case generic } -public func resendTwoStepRecoveryEmail(network: Network) -> Signal { +func _internal_resendTwoStepRecoveryEmail(network: Network) -> Signal { return network.request(Api.functions.account.resendPasswordEmail(), automaticFloodWait: false) |> mapError { error -> ResendTwoStepRecoveryEmailError in if error.errorDescription.hasPrefix("FLOOD_WAIT") { @@ -49,7 +49,7 @@ public enum CancelTwoStepRecoveryEmailError { case generic } -public func cancelTwoStepRecoveryEmail(network: Network) -> Signal { +func _internal_cancelTwoStepRecoveryEmail(network: Network) -> Signal { return network.request(Api.functions.account.cancelPasswordEmail(), automaticFloodWait: false) |> mapError { _ -> CancelTwoStepRecoveryEmailError in return .generic diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift index d9dbf133d0..a23fcd2d02 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TelegramEngineAuth.swift @@ -1,6 +1,8 @@ import SwiftSignalKit import Postbox import TelegramApi +import MtProtoKit +import SyncCore public extension TelegramEngineUnauthorized { final class Auth { @@ -13,6 +15,22 @@ public extension TelegramEngineUnauthorized { public func exportAuthTransferToken(accountManager: AccountManager, otherAccountUserIds: [PeerId.Id], syncContacts: Bool) -> Signal { return _internal_exportAuthTransferToken(accountManager: accountManager, account: self.account, otherAccountUserIds: otherAccountUserIds, syncContacts: syncContacts) } + + public func twoStepAuthData() -> Signal { + return _internal_twoStepAuthData(self.account.network) + } + + public func updateTwoStepVerificationPassword(currentPassword: String?, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { + return _internal_updateTwoStepVerificationPassword(network: self.account.network, currentPassword: currentPassword, updatedPassword: updatedPassword) + } + + public func performPasswordRecovery(accountManager: AccountManager, code: String, syncContacts: Bool, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { + return _internal_performPasswordRecovery(accountManager: accountManager, account: self.account, code: code, syncContacts: syncContacts, updatedPassword: updatedPassword) + } + + public func resendTwoStepRecoveryEmail() -> Signal { + return _internal_resendTwoStepRecoveryEmail(network: self.account.network) + } } } @@ -21,19 +39,120 @@ public enum DeleteAccountError { } public extension TelegramEngine { - final class Auth { - private let account: Account + final class Auth { + private let account: Account - init(account: Account) { - self.account = account - } + init(account: Account) { + self.account = account + } - public func deleteAccount() -> Signal { - return self.account.network.request(Api.functions.account.deleteAccount(reason: "GDPR")) - |> mapError { _ -> DeleteAccountError in - return .generic - } - |> ignoreValues - } - } + public func twoStepAuthData() -> Signal { + return _internal_twoStepAuthData(self.account.network) + } + + public func updateTwoStepVerificationPassword(currentPassword: String?, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { + return _internal_updateTwoStepVerificationPassword(network: self.account.network, currentPassword: currentPassword, updatedPassword: updatedPassword) + } + + public func deleteAccount() -> Signal { + return self.account.network.request(Api.functions.account.deleteAccount(reason: "GDPR")) + |> mapError { _ -> DeleteAccountError in + return .generic + } + |> ignoreValues + } + + public func updateTwoStepVerificationEmail(currentPassword: String, updatedEmail: String) -> Signal { + return _internal_updateTwoStepVerificationEmail(network: self.account.network, currentPassword: currentPassword, updatedEmail: updatedEmail) + } + + public func confirmTwoStepRecoveryEmail(code: String) -> Signal { + return _internal_confirmTwoStepRecoveryEmail(network: self.account.network, code: code) + } + + public func resendTwoStepRecoveryEmail() -> Signal { + return _internal_resendTwoStepRecoveryEmail(network: self.account.network) + } + + public func cancelTwoStepRecoveryEmail() -> Signal { + return _internal_cancelTwoStepRecoveryEmail(network: self.account.network) + } + + public func twoStepVerificationConfiguration() -> Signal { + return _internal_twoStepVerificationConfiguration(account: self.account) + } + + public func requestTwoStepVerifiationSettings(password: String) -> Signal { + return _internal_requestTwoStepVerifiationSettings(network: self.account.network, password: password) + } + + public func requestTwoStepVerificationPasswordRecoveryCode() -> Signal { + return _internal_requestTwoStepVerificationPasswordRecoveryCode(network: self.account.network) + } + + public func recoverTwoStepVerificationPassword(code: String) -> Signal { + return _internal_recoverTwoStepVerificationPassword(network: self.account.network, code: code) + } + + public func cachedTwoStepPasswordToken() -> Signal { + return _internal_cachedTwoStepPasswordToken(postbox: self.account.postbox) + } + + public func cacheTwoStepPasswordToken(token: TemporaryTwoStepPasswordToken?) -> Signal { + return _internal_cacheTwoStepPasswordToken(postbox: self.account.postbox, token: token) + } + + public func requestTemporaryTwoStepPasswordToken(password: String, period: Int32, requiresBiometrics: Bool) -> Signal { + return _internal_requestTemporaryTwoStepPasswordToken(account: self.account, password: password, period: period, requiresBiometrics: requiresBiometrics) + } + + public func requestTwoStepPasswordReset() -> Signal { + return _internal_requestTwoStepPasswordReset(network: self.account.network) + } + + public func declineTwoStepPasswordReset() -> Signal { + return _internal_declineTwoStepPasswordReset(network: self.account.network) + } + } +} + +public extension SomeTelegramEngine { + final class Auth { + private let engine: SomeTelegramEngine + + init(engine: SomeTelegramEngine) { + self.engine = engine + } + + public func twoStepAuthData() -> Signal { + switch self.engine { + case let .authorized(engine): + return engine.auth.twoStepAuthData() + case let .unauthorized(engine): + return engine.auth.twoStepAuthData() + } + } + + public func updateTwoStepVerificationPassword(currentPassword: String?, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { + switch self.engine { + case let .authorized(engine): + return engine.auth.updateTwoStepVerificationPassword(currentPassword: currentPassword, updatedPassword: updatedPassword) + case let .unauthorized(engine): + return engine.auth.updateTwoStepVerificationPassword(currentPassword: currentPassword, updatedPassword: updatedPassword) + } + } + + public func resendTwoStepRecoveryEmail() -> Signal { + switch self.engine { + case let .authorized(engine): + return engine.auth.resendTwoStepRecoveryEmail() + case let .unauthorized(engine): + return engine.auth.resendTwoStepRecoveryEmail() + } + } + } + + var auth: Auth { + return Auth(engine: self) + } } diff --git a/submodules/TelegramCore/Sources/TwoStepVerification.swift b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift similarity index 90% rename from submodules/TelegramCore/Sources/TwoStepVerification.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift index 08bcc49353..e48acb914b 100644 --- a/submodules/TelegramCore/Sources/TwoStepVerification.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Auth/TwoStepVerification.swift @@ -11,7 +11,7 @@ public enum TwoStepVerificationConfiguration { case set(hint: String, hasRecoveryEmail: Bool, pendingEmail: TwoStepVerificationPendingEmail?, hasSecureValues: Bool, pendingResetTimestamp: Int32?) } -public func twoStepVerificationConfiguration(account: Account) -> Signal { +func _internal_twoStepVerificationConfiguration(account: Account) -> Signal { return account.network.request(Api.functions.account.getPassword()) |> retryRequest |> map { result -> TwoStepVerificationConfiguration in @@ -37,8 +37,8 @@ public struct TwoStepVerificationSettings { public let secureSecret: TwoStepVerificationSecureSecret? } -public func requestTwoStepVerifiationSettings(network: Network, password: String) -> Signal { - return twoStepAuthData(network) +func _internal_requestTwoStepVerifiationSettings(network: Network, password: String) -> Signal { + return _internal_twoStepAuthData(network) |> mapError { error -> AuthorizationPasswordVerificationError in if error.errorDescription.hasPrefix("FLOOD_WAIT") { return .limitExceeded @@ -111,14 +111,14 @@ public enum UpdatedTwoStepVerificationPassword { case password(password: String, hint: String, email: String?) } -public func updateTwoStepVerificationPassword(network: Network, currentPassword: String?, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { - return twoStepAuthData(network) +func _internal_updateTwoStepVerificationPassword(network: Network, currentPassword: String?, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal { + return _internal_twoStepAuthData(network) |> mapError { _ -> UpdateTwoStepVerificationPasswordError in return .generic } |> mapToSignal { authData -> Signal in if let _ = authData.currentPasswordDerivation { - return requestTwoStepVerifiationSettings(network: network, password: currentPassword ?? "") + return _internal_requestTwoStepVerifiationSettings(network: network, password: currentPassword ?? "") |> mapError { _ -> UpdateTwoStepVerificationPasswordError in return .generic } @@ -130,7 +130,7 @@ public func updateTwoStepVerificationPassword(network: Network, currentPassword: } } |> mapToSignal { secureSecret -> Signal<(TwoStepAuthData, TwoStepVerificationSecureSecret?), UpdateTwoStepVerificationPasswordError> in - return twoStepAuthData(network) + return _internal_twoStepAuthData(network) |> mapError { _ -> UpdateTwoStepVerificationPasswordError in return .generic } @@ -205,7 +205,7 @@ public func updateTwoStepVerificationPassword(network: Network, currentPassword: codeLength = value } } - return twoStepAuthData(network) + return _internal_twoStepAuthData(network) |> map { result -> UpdateTwoStepVerificationPasswordResult in return .password(password: password, pendingEmail: result.unconfirmedEmailPattern.flatMap({ TwoStepVerificationPendingEmail(pattern: $0, codeLength: codeLength) })) } @@ -233,7 +233,7 @@ enum UpdateTwoStepVerificationSecureSecretError { } func updateTwoStepVerificationSecureSecret(network: Network, password: String, secret: Data) -> Signal { - return twoStepAuthData(network) + return _internal_twoStepAuthData(network) |> mapError { _ -> UpdateTwoStepVerificationSecureSecretError in return .generic } @@ -263,8 +263,8 @@ func updateTwoStepVerificationSecureSecret(network: Network, password: String, s } } -public func updateTwoStepVerificationEmail(network: Network, currentPassword: String, updatedEmail: String) -> Signal { - return twoStepAuthData(network) +func _internal_updateTwoStepVerificationEmail(network: Network, currentPassword: String, updatedEmail: String) -> Signal { + return _internal_twoStepAuthData(network) |> mapError { _ -> UpdateTwoStepVerificationPasswordError in return .generic } @@ -286,7 +286,7 @@ public func updateTwoStepVerificationEmail(network: Network, currentPassword: St } |> `catch` { error -> Signal in if error.errorDescription.hasPrefix("EMAIL_UNCONFIRMED") { - return twoStepAuthData(network) + return _internal_twoStepAuthData(network) |> map { result -> UpdateTwoStepVerificationPasswordResult in var codeLength: Int32? if error.errorDescription.hasPrefix("EMAIL_UNCONFIRMED_") { @@ -314,7 +314,7 @@ public enum RequestTwoStepVerificationPasswordRecoveryCodeError { case generic } -public func requestTwoStepVerificationPasswordRecoveryCode(network: Network) -> Signal { +func _internal_requestTwoStepVerificationPasswordRecoveryCode(network: Network) -> Signal { return network.request(Api.functions.auth.requestPasswordRecovery(), automaticFloodWait: false) |> mapError { _ -> RequestTwoStepVerificationPasswordRecoveryCodeError in return .generic @@ -334,8 +334,8 @@ public enum RecoverTwoStepVerificationPasswordError { case invalidCode } -public func recoverTwoStepVerificationPassword(network: Network, code: String) -> Signal { - return twoStepAuthData(network) +func _internal_recoverTwoStepVerificationPassword(network: Network, code: String) -> Signal { + return _internal_twoStepAuthData(network) |> mapError { _ -> RecoverTwoStepVerificationPasswordError in return .generic } @@ -363,7 +363,7 @@ public func recoverTwoStepVerificationPassword(network: Network, code: String) - } } -public func cachedTwoStepPasswordToken(postbox: Postbox) -> Signal { +func _internal_cachedTwoStepPasswordToken(postbox: Postbox) -> Signal { return postbox.transaction { transaction -> TemporaryTwoStepPasswordToken? in let key = ValueBoxKey(length: 1) key.setUInt8(0, value: 0) @@ -371,7 +371,7 @@ public func cachedTwoStepPasswordToken(postbox: Postbox) -> Signal Signal { +func _internal_cacheTwoStepPasswordToken(postbox: Postbox, token: TemporaryTwoStepPasswordToken?) -> Signal { return postbox.transaction { transaction -> Void in let key = ValueBoxKey(length: 1) key.setUInt8(0, value: 0) @@ -383,8 +383,8 @@ public func cacheTwoStepPasswordToken(postbox: Postbox, token: TemporaryTwoStepP } } -public func requestTemporaryTwoStepPasswordToken(account: Account, password: String, period: Int32, requiresBiometrics: Bool) -> Signal { - return twoStepAuthData(account.network) +func _internal_requestTemporaryTwoStepPasswordToken(account: Account, password: String, period: Int32, requiresBiometrics: Bool) -> Signal { + return _internal_twoStepAuthData(account.network) |> mapToSignal { authData -> Signal in guard let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData else { return .fail(MTRpcError(errorCode: 400, errorDescription: "NO_PASSWORD")) @@ -426,7 +426,7 @@ public enum RequestTwoStepPasswordResetResult { case error(reason: ErrorReason) } -public func requestTwoStepPasswordReset(network: Network) -> Signal { +func _internal_requestTwoStepPasswordReset(network: Network) -> Signal { return network.request(Api.functions.account.resetPassword(), automaticFloodWait: false) |> map { _ -> RequestTwoStepPasswordResetResult in return .done @@ -456,7 +456,7 @@ public func requestTwoStepPasswordReset(network: Network) -> Signal Signal { +func _internal_declineTwoStepPasswordReset(network: Network) -> Signal { return network.request(Api.functions.account.declinePasswordReset()) |> `catch` { _ -> Signal in return .single(.boolFalse) diff --git a/submodules/TelegramCore/Sources/RateCall.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/RateCall.swift similarity index 75% rename from submodules/TelegramCore/Sources/RateCall.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Calls/RateCall.swift index bac6cd7258..7a8ed6ebee 100644 --- a/submodules/TelegramCore/Sources/RateCall.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/RateCall.swift @@ -4,7 +4,7 @@ import MtProtoKit import SwiftSignalKit import TelegramApi -public func rateCall(account: Account, callId: CallId, starsCount: Int32, comment: String = "", userInitiated: Bool) -> Signal { +func _internal_rateCall(account: Account, callId: CallId, starsCount: Int32, comment: String = "", userInitiated: Bool) -> Signal { var flags: Int32 = 0 if userInitiated { flags |= (1 << 0) @@ -14,7 +14,7 @@ public func rateCall(account: Account, callId: CallId, starsCount: Int32, commen |> map { _ in } } -public func saveCallDebugLog(network: Network, callId: CallId, log: String) -> Signal { +func _internal_saveCallDebugLog(network: Network, callId: CallId, log: String) -> Signal { if log.count > 1024 * 16 { return .complete() } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift b/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift new file mode 100644 index 0000000000..8f2dd214df --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/Calls/TelegramEngineCalls.swift @@ -0,0 +1,19 @@ +import SwiftSignalKit + +public extension TelegramEngine { + final class Calls { + private let account: Account + + init(account: Account) { + self.account = account + } + + public func rateCall(callId: CallId, starsCount: Int32, comment: String = "", userInitiated: Bool) -> Signal { + return _internal_rateCall(account: self.account, callId: callId, starsCount: starsCount, comment: comment, userInitiated: userInitiated) + } + + public func saveCallDebugLog(callId: CallId, log: String) -> Signal { + return _internal_saveCallDebugLog(network: self.account.network, callId: callId, log: log) + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/HistoryImport/TelegramEngineHistoryImport.swift b/submodules/TelegramCore/Sources/TelegramEngine/HistoryImport/TelegramEngineHistoryImport.swift new file mode 100644 index 0000000000..309c0673a0 --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/HistoryImport/TelegramEngineHistoryImport.swift @@ -0,0 +1,255 @@ +import Foundation +import SwiftSignalKit +import Postbox +import SyncCore +import TelegramApi + +public extension TelegramEngine { + final class HistoryImport { + private let account: Account + + init(account: Account) { + self.account = account + } + + public struct Session { + fileprivate var peerId: PeerId + fileprivate var inputPeer: Api.InputPeer + fileprivate var id: Int64 + } + + public enum InitImportError { + case generic + case chatAdminRequired + case invalidChatType + case userBlocked + case limitExceeded + } + + public enum ParsedInfo { + case privateChat(title: String?) + case group(title: String?) + case unknown(title: String?) + } + + public enum GetInfoError { + case generic + case parseError + } + + public func getInfo(header: String) -> Signal { + return self.account.network.request(Api.functions.messages.checkHistoryImport(importHead: header)) + |> mapError { _ -> GetInfoError in + return .generic + } + |> mapToSignal { result -> Signal in + switch result { + case let .historyImportParsed(flags, title): + if (flags & (1 << 0)) != 0 { + return .single(.privateChat(title: title)) + } else if (flags & (1 << 1)) != 0 { + return .single(.group(title: title)) + } else { + return .single(.unknown(title: title)) + } + } + } + } + + public func initSession(peerId: PeerId, file: TempBoxFile, mediaCount: Int32) -> Signal { + let account = self.account + return multipartUpload(network: self.account.network, postbox: self.account.postbox, source: .tempFile(file), encrypt: false, tag: nil, hintFileSize: nil, hintFileIsLarge: false, forceNoBigParts: true, useLargerParts: true, increaseParallelParts: true, useMultiplexedRequests: false, useCompression: true) + |> mapError { _ -> InitImportError in + return .generic + } + |> mapToSignal { result -> Signal in + switch result { + case let .inputFile(inputFile): + return account.postbox.transaction { transaction -> Api.InputPeer? in + return transaction.getPeer(peerId).flatMap(apiInputPeer) + } + |> castError(InitImportError.self) + |> mapToSignal { inputPeer -> Signal in + guard let inputPeer = inputPeer else { + return .fail(.generic) + } + return account.network.request(Api.functions.messages.initHistoryImport(peer: inputPeer, file: inputFile, mediaCount: mediaCount), automaticFloodWait: false) + |> mapError { error -> InitImportError in + if error.errorDescription == "CHAT_ADMIN_REQUIRED" { + return .chatAdminRequired + } else if error.errorDescription == "IMPORT_PEER_TYPE_INVALID" { + return .invalidChatType + } else if error.errorDescription == "USER_IS_BLOCKED" { + return .userBlocked + } else if error.errorDescription == "FLOOD_WAIT" { + return .limitExceeded + } else { + return .generic + } + } + |> map { result -> Session in + switch result { + case let .historyImport(id): + return Session(peerId: peerId, inputPeer: inputPeer, id: id) + } + } + } + case .progress: + return .complete() + case .inputSecretFile: + return .fail(.generic) + } + } + } + + public enum MediaType { + case photo + case file + case video + case sticker + case voice + } + + public enum UploadMediaError { + case generic + case chatAdminRequired + } + + public func uploadMedia(session: Session, file: TempBoxFile, disposeFileAfterDone: Bool, fileName: String, mimeType: String, type: MediaType) -> Signal { + var forceNoBigParts = true + guard let size = fileSize(file.path), size != 0 else { + return .single(1.0) + } + if size >= 30 * 1024 * 1024 { + forceNoBigParts = false + } + + let account = self.account + return multipartUpload(network: self.account.network, postbox: self.account.postbox, source: .tempFile(file), encrypt: false, tag: nil, hintFileSize: nil, hintFileIsLarge: false, forceNoBigParts: forceNoBigParts, useLargerParts: true, useMultiplexedRequests: true) + |> mapError { _ -> UploadMediaError in + return .generic + } + |> mapToSignal { result -> Signal in + let inputMedia: Api.InputMedia + switch result { + case let .inputFile(inputFile): + switch type { + case .photo: + inputMedia = .inputMediaUploadedPhoto(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil) + case .file, .video, .sticker, .voice: + var attributes: [Api.DocumentAttribute] = [] + attributes.append(.documentAttributeFilename(fileName: fileName)) + var resolvedMimeType = mimeType + switch type { + case .video: + resolvedMimeType = "video/mp4" + case .sticker: + resolvedMimeType = "image/webp" + case .voice: + resolvedMimeType = "audio/ogg" + default: + break + } + inputMedia = .inputMediaUploadedDocument(flags: 0, file: inputFile, thumb: nil, mimeType: resolvedMimeType, attributes: attributes, stickers: nil, ttlSeconds: nil) + } + case let .progress(value): + return .single(value) + case .inputSecretFile: + return .fail(.generic) + } + return account.network.request(Api.functions.messages.uploadImportedMedia(peer: session.inputPeer, importId: session.id, fileName: fileName, media: inputMedia)) + |> mapError { error -> UploadMediaError in + switch error.errorDescription { + case "CHAT_ADMIN_REQUIRED": + return .chatAdminRequired + default: + return .generic + } + } + |> mapToSignal { result -> Signal in + return .single(1.0) + } + |> afterDisposed { + if disposeFileAfterDone { + TempBox.shared.dispose(file) + } + } + } + } + + public enum StartImportError { + case generic + } + + public func startImport(session: Session) -> Signal { + return self.account.network.request(Api.functions.messages.startHistoryImport(peer: session.inputPeer, importId: session.id)) + |> mapError { _ -> StartImportError in + return .generic + } + |> mapToSignal { result -> Signal in + if case .boolTrue = result { + return .complete() + } else { + return .fail(.generic) + } + } + } + + public enum CheckPeerImportResult { + case allowed + case alert(String) + } + + public enum CheckPeerImportError { + case generic + case chatAdminRequired + case invalidChatType + case userBlocked + case limitExceeded + case notMutualContact + } + + public func checkPeerImport(peerId: PeerId) -> Signal { + let account = self.account + return self.account.postbox.transaction { transaction -> Peer? in + return transaction.getPeer(peerId) + } + |> castError(CheckPeerImportError.self) + |> mapToSignal { peer -> Signal in + guard let peer = peer else { + return .fail(.generic) + } + guard let inputPeer = apiInputPeer(peer) else { + return .fail(.generic) + } + + return account.network.request(Api.functions.messages.checkHistoryImportPeer(peer: inputPeer)) + |> mapError { error -> CheckPeerImportError in + if error.errorDescription == "CHAT_ADMIN_REQUIRED" { + return .chatAdminRequired + } else if error.errorDescription == "IMPORT_PEER_TYPE_INVALID" { + return .invalidChatType + } else if error.errorDescription == "USER_IS_BLOCKED" { + return .userBlocked + } else if error.errorDescription == "USER_NOT_MUTUAL_CONTACT" { + return .notMutualContact + } else if error.errorDescription == "FLOOD_WAIT" { + return .limitExceeded + } else { + return .generic + } + } + |> map { result -> CheckPeerImportResult in + switch result { + case let .checkedHistoryImportPeer(confirmText): + if confirmText.isEmpty { + return .allowed + } else { + return .alert(confirmText) + } + } + } + } + } + } +} diff --git a/submodules/TelegramCore/Sources/ForwardGame.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift similarity index 89% rename from submodules/TelegramCore/Sources/ForwardGame.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift index f41b02e57b..7a592178fa 100644 --- a/submodules/TelegramCore/Sources/ForwardGame.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/ForwardGame.swift @@ -3,7 +3,7 @@ import Postbox import TelegramApi import SwiftSignalKit -public func forwardGameWithScore(account: Account, messageId: MessageId, to peerId: PeerId) -> Signal { +func _internal_forwardGameWithScore(account: Account, messageId: MessageId, to peerId: PeerId) -> Signal { return account.postbox.transaction { transaction -> Signal in if let _ = transaction.getMessage(messageId), let fromPeer = transaction.getPeer(messageId.peerId), let fromInputPeer = apiInputPeer(fromPeer), let toPeer = transaction.getPeer(peerId), let toInputPeer = apiInputPeer(toPeer) { return account.network.request(Api.functions.messages.forwardMessages(flags: 1 << 8, fromPeer: fromInputPeer, id: [messageId.id], randomId: [Int64.random(in: Int64.min ... Int64.max)], toPeer: toInputPeer, scheduleDate: nil)) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/RequestMessageActionCallback.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/RequestMessageActionCallback.swift index 614c827368..6bfa85422f 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/RequestMessageActionCallback.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/RequestMessageActionCallback.swift @@ -92,7 +92,7 @@ func _internal_requestMessageActionCallback(account: Account, messageId: Message if let password = password, !password.isEmpty { flags |= Int32(1 << 2) - checkPassword = twoStepAuthData(account.network) + checkPassword = _internal_twoStepAuthData(account.network) |> mapError { error -> MessageActionCallbackError in if error.errorDescription.hasPrefix("FLOOD_WAIT") { return .limitExceeded diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift index df12d4c2db..46a4e7a7d6 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/TelegramEngineMessages.swift @@ -85,5 +85,14 @@ public extension TelegramEngine { public func requestEditLiveLocation(messageId: MessageId, stop: Bool, coordinate: (latitude: Double, longitude: Double, accuracyRadius: Int32?)?, heading: Int32?, proximityNotificationRadius: Int32?) -> Signal { return _internal_requestEditLiveLocation(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, messageId: messageId, stop: stop, coordinate: coordinate, heading: heading, proximityNotificationRadius: proximityNotificationRadius) } + + public func addSecretChatMessageScreenshot(peerId: PeerId) -> Signal { + return _internal_addSecretChatMessageScreenshot(account: self.account, peerId: peerId) + |> ignoreValues + } + + public func forwardGameWithScore(messageId: MessageId, to peerId: PeerId) -> Signal { + return _internal_forwardGameWithScore(account: self.account, messageId: messageId, to: peerId) + } } } diff --git a/submodules/TelegramCore/Sources/GroupsInCommon.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/GroupsInCommon.swift similarity index 79% rename from submodules/TelegramCore/Sources/GroupsInCommon.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Peers/GroupsInCommon.swift index 53a5450cad..9fad743857 100644 --- a/submodules/TelegramCore/Sources/GroupsInCommon.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/GroupsInCommon.swift @@ -154,36 +154,3 @@ public final class GroupsInCommonContext { } } } - -public func groupsInCommon(account: Account, peerId: PeerId) -> Signal<[Peer], NoError> { - return account.postbox.transaction { transaction -> Signal<[Peer], NoError> in - if let peer = transaction.getPeer(peerId), let inputUser = apiInputUser(peer) { - return account.network.request(Api.functions.messages.getCommonChats(userId: inputUser, maxId: 0, limit: 100)) - |> retryRequest - |> mapToSignal { result -> Signal<[Peer], NoError> in - let chats: [Api.Chat] - switch result { - case let .chats(chats: apiChats): - chats = apiChats - case let .chatsSlice(count: _, chats: apiChats): - chats = apiChats - } - - return account.postbox.transaction { transaction -> [Peer] in - var peers: [Peer] = [] - for chat in chats { - if let peer = parseTelegramGroupOrChannel(chat: chat) { - peers.append(peer) - } - } - updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer? in - return updated - }) - return peers - } - } - } else { - return .single([]) - } - } |> switchToLatest -} diff --git a/submodules/TelegramCore/Sources/ReportPeer.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ReportPeer.swift similarity index 93% rename from submodules/TelegramCore/Sources/ReportPeer.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Peers/ReportPeer.swift index 34cb965184..f37a6edf10 100644 --- a/submodules/TelegramCore/Sources/ReportPeer.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ReportPeer.swift @@ -6,7 +6,7 @@ import MtProtoKit import SyncCore -public func reportPeer(account: Account, peerId: PeerId) -> Signal { +func _internal_reportPeer(account: Account, peerId: PeerId) -> Signal { return account.postbox.transaction { transaction -> Signal in if let peer = transaction.getPeer(peerId) { if let peer = peer as? TelegramSecretChat { @@ -110,7 +110,7 @@ private extension ReportReason { } } -public func reportPeer(account: Account, peerId: PeerId, reason: ReportReason, message: String) -> Signal { +func _internal_reportPeer(account: Account, peerId: PeerId, reason: ReportReason, message: String) -> Signal { return account.postbox.transaction { transaction -> Signal in if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) { return account.network.request(Api.functions.account.reportPeer(peer: inputPeer, reason: reason.apiReason, message: message)) @@ -126,7 +126,7 @@ public func reportPeer(account: Account, peerId: PeerId, reason: ReportReason, m } |> switchToLatest } -public func reportPeerPhoto(account: Account, peerId: PeerId, reason: ReportReason, message: String) -> Signal { +func _internal_reportPeerPhoto(account: Account, peerId: PeerId, reason: ReportReason, message: String) -> Signal { return account.postbox.transaction { transaction -> Signal in if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) { return account.network.request(Api.functions.account.reportProfilePhoto(peer: inputPeer, photoId: .inputPhotoEmpty, reason: reason.apiReason, message: message)) @@ -142,7 +142,7 @@ public func reportPeerPhoto(account: Account, peerId: PeerId, reason: ReportReas } |> switchToLatest } -public func reportPeerMessages(account: Account, messageIds: [MessageId], reason: ReportReason, message: String) -> Signal { +func _internal_reportPeerMessages(account: Account, messageIds: [MessageId], reason: ReportReason, message: String) -> Signal { return account.postbox.transaction { transaction -> Signal in let groupedIds = messagesIdsGroupedByPeerId(messageIds) let signals = groupedIds.values.compactMap { ids -> Signal? in @@ -165,7 +165,7 @@ public func reportPeerMessages(account: Account, messageIds: [MessageId], reason } |> switchToLatest } -public func dismissPeerStatusOptions(account: Account, peerId: PeerId) -> Signal { +func _internal_dismissPeerStatusOptions(account: Account, peerId: PeerId) -> Signal { return account.postbox.transaction { transaction -> Signal in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in if let current = current as? CachedUserData { @@ -203,7 +203,7 @@ public func dismissPeerStatusOptions(account: Account, peerId: PeerId) -> Signal } |> switchToLatest } -public func reportRepliesMessage(account: Account, messageId: MessageId, deleteMessage: Bool, deleteHistory: Bool, reportSpam: Bool) -> Signal { +func _internal_reportRepliesMessage(account: Account, messageId: MessageId, deleteMessage: Bool, deleteHistory: Bool, reportSpam: Bool) -> Signal { if messageId.namespace != Namespaces.Message.Cloud { return .complete() } diff --git a/submodules/TelegramCore/Sources/SlowMode.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/SlowMode.swift similarity index 86% rename from submodules/TelegramCore/Sources/SlowMode.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Peers/SlowMode.swift index 7134b47d08..a2f3ee94f0 100644 --- a/submodules/TelegramCore/Sources/SlowMode.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/SlowMode.swift @@ -9,7 +9,7 @@ public enum UpdateChannelSlowModeError { case tooManyChannels } -public func updateChannelSlowModeInteractively(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, peerId: PeerId, timeout: Int32?) -> Signal { +func _internal_updateChannelSlowModeInteractively(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, peerId: PeerId, timeout: Int32?) -> Signal { return postbox.transaction { transaction -> Peer? in return transaction.getPeer(peerId) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 4ce9e85463..bf253708bd 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -92,7 +92,41 @@ public extension TelegramEngine { } public func setChatMessageAutoremoveTimeoutInteractively(peerId: PeerId, timeout: Int32?) -> Signal { - return _internal_setChatMessageAutoremoveTimeoutInteractively(account: self.account, peerId: peerId, timeout: timeout) + if peerId.namespace == Namespaces.Peer.SecretChat { + return _internal_setSecretChatMessageAutoremoveTimeoutInteractively(account: self.account, peerId: peerId, timeout: timeout) + |> ignoreValues + |> castError(SetChatMessageAutoremoveTimeoutError.self) + } else { + return _internal_setChatMessageAutoremoveTimeoutInteractively(account: self.account, peerId: peerId, timeout: timeout) + } + } + + public func updateChannelSlowModeInteractively(peerId: PeerId, timeout: Int32?) -> Signal { + return _internal_updateChannelSlowModeInteractively(postbox: self.account.postbox, network: self.account.network, accountStateManager: self.account.stateManager, peerId: peerId, timeout: timeout) + } + + public func reportPeer(peerId: PeerId) -> Signal { + return _internal_reportPeer(account: self.account, peerId: peerId) + } + + public func reportPeer(peerId: PeerId, reason: ReportReason, message: String) -> Signal { + return _internal_reportPeer(account: self.account, peerId: peerId, reason: reason, message: message) + } + + public func reportPeerPhoto(peerId: PeerId, reason: ReportReason, message: String) -> Signal { + return _internal_reportPeerPhoto(account: self.account, peerId: peerId, reason: reason, message: message) + } + + public func reportPeerMessages(messageIds: [MessageId], reason: ReportReason, message: String) -> Signal { + return _internal_reportPeerMessages(account: account, messageIds: messageIds, reason: reason, message: message) + } + + public func dismissPeerStatusOptions(peerId: PeerId) -> Signal { + return _internal_dismissPeerStatusOptions(account: self.account, peerId: peerId) + } + + public func reportRepliesMessage(messageId: MessageId, deleteMessage: Bool, deleteHistory: Bool, reportSpam: Bool) -> Signal { + return _internal_reportRepliesMessage(account: self.account, messageId: messageId, deleteMessage: deleteMessage, deleteHistory: deleteHistory, reportSpam: reportSpam) } } } diff --git a/submodules/TelegramCore/Sources/BlockedPeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/BlockedPeers.swift similarity index 96% rename from submodules/TelegramCore/Sources/BlockedPeers.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Privacy/BlockedPeers.swift index c671ed35a4..bd5794c41c 100644 --- a/submodules/TelegramCore/Sources/BlockedPeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/BlockedPeers.swift @@ -41,7 +41,7 @@ public func requestBlockedPeers(account: Account) -> Signal<[Peer], NoError> { } } -public func requestUpdatePeerIsBlocked(account: Account, peerId: PeerId, isBlocked: Bool) -> Signal { +func _internal_requestUpdatePeerIsBlocked(account: Account, peerId: PeerId, isBlocked: Bool) -> Signal { return account.postbox.transaction { transaction -> Signal in if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) { let signal: Signal diff --git a/submodules/TelegramCore/Sources/BlockedPeersContext.swift b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/BlockedPeersContext.swift similarity index 99% rename from submodules/TelegramCore/Sources/BlockedPeersContext.swift rename to submodules/TelegramCore/Sources/TelegramEngine/Privacy/BlockedPeersContext.swift index 06985ae459..fae1f08062 100644 --- a/submodules/TelegramCore/Sources/BlockedPeersContext.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/BlockedPeersContext.swift @@ -3,7 +3,6 @@ import TelegramApi import Postbox import SwiftSignalKit import MtProtoKit - import SyncCore public struct BlockedPeersContextState: Equatable { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Privacy/TelegramEnginePrivacy.swift b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/TelegramEnginePrivacy.swift new file mode 100644 index 0000000000..807a6c1a58 --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/Privacy/TelegramEnginePrivacy.swift @@ -0,0 +1,16 @@ +import SwiftSignalKit +import Postbox + +public extension TelegramEngine { + final class Privacy { + private let account: Account + + init(account: Account) { + self.account = account + } + + public func requestUpdatePeerIsBlocked(peerId: PeerId, isBlocked: Bool) -> Signal { + return _internal_requestUpdatePeerIsBlocked(account: self.account, peerId: peerId, isBlocked: isBlocked) + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/AccessSecureId.swift b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/AccessSecureId.swift index 196162d568..96e678f46e 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/AccessSecureId.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/AccessSecureId.swift @@ -154,7 +154,7 @@ public enum SecureIdAccessError { } func _internal_accessSecureId(network: Network, password: String) -> Signal<(context: SecureIdAccessContext, settings: TwoStepVerificationSettings), SecureIdAccessError> { - return requestTwoStepVerifiationSettings(network: network, password: password) + return _internal_requestTwoStepVerifiationSettings(network: network, password: password) |> mapError { error -> SecureIdAccessError in return .passwordError(error) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift index 06fb9d5cdb..1523513f4c 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/SecureId/SaveSecureIdValue.swift @@ -276,7 +276,7 @@ public func deleteSecureIdValues(network: Network, keys: Set) } public func dropSecureId(network: Network, currentPassword: String) -> Signal { - return twoStepAuthData(network) + return _internal_twoStepAuthData(network) |> mapError { _ -> AuthorizationPasswordVerificationError in return .generic } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift b/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift index 9fd8d6412e..c246adbccc 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/TelegramEngine.swift @@ -47,6 +47,18 @@ public final class TelegramEngine { public lazy var messages: Messages = { return Messages(account: self.account) }() + + public lazy var privacy: Privacy = { + return Privacy(account: self.account) + }() + + public lazy var calls: Calls = { + return Calls(account: self.account) + }() + + public lazy var historyImport: HistoryImport = { + return HistoryImport(account: self.account) + }() } public final class TelegramEngineUnauthorized { @@ -64,3 +76,8 @@ public final class TelegramEngineUnauthorized { return Localization(account: self.account) }() } + +public enum SomeTelegramEngine { + case unauthorized(TelegramEngineUnauthorized) + case authorized(TelegramEngine) +} diff --git a/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift b/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift index 30c410b7dd..f9530e9873 100644 --- a/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift +++ b/submodules/TelegramUI/Sources/AuthorizationSequenceController.swift @@ -597,7 +597,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } controller?.inProgress = false - let setupController = TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, network: strongSelf.account.network, mode: .passwordRecovery(TwoFactorDataInputMode.Recovery(code: code, syncContacts: syncContacts, account: strongSelf.account)), stateUpdated: { _ in + let setupController = TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: .unauthorized(TelegramEngineUnauthorized(account: strongSelf.account)), mode: .passwordRecovery(TwoFactorDataInputMode.Recovery(code: code, syncContacts: syncContacts, account: strongSelf.account)), stateUpdated: { _ in guard let _ = self else { return } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 2f7d3a8833..5f9bedcc9d 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -5045,7 +5045,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G items.append(ActionSheetButtonItem(title: presentationData.strings.Report_Report, color: .accent, font: .bold, enabled: true, action: { dismissAction() strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } }, completion: { _ in - let _ = (reportPeerMessages(account: strongSelf.context.account, messageIds: Array(messageIds), reason: reportReason, message: message) + let _ = (strongSelf.context.engine.peers.reportPeerMessages(messageIds: Array(messageIds), reason: reportReason, message: message) |> deliverOnMainQueue).start(completed: { [weak self] in if let strongSelf = self, let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") { strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .emoji(path: path, text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current) @@ -5110,12 +5110,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - let _ = requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: true).start() + let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).start() let context = strongSelf.context let _ = (context.account.postbox.transaction { transasction -> Void in context.engine.messages.deleteAllMessagesWithForwardAuthor(transaction: transasction, peerId: message.id.peerId, forwardAuthorId: peer.id, namespace: Namespaces.Message.Cloud) }).start() - let _ = reportRepliesMessage(account: strongSelf.context.account, messageId: message.id, deleteMessage: true, deleteHistory: true, reportSpam: reportSpam).start() + let _ = strongSelf.context.engine.peers.reportRepliesMessage(messageId: message.id, deleteMessage: true, deleteHistory: true, reportSpam: reportSpam).start() }) ] as [ActionSheetItem]) @@ -5815,7 +5815,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let peer = peer as? TelegramSecretChat { let controller = ChatSecretAutoremoveTimerActionSheetController(context: strongSelf.context, currentValue: peer.messageAutoremoveTimeout == nil ? 0 : peer.messageAutoremoveTimeout!, applyValue: { value in if let strongSelf = self { - let _ = setSecretChatMessageAutoremoveTimeoutInteractively(account: strongSelf.context.account, peerId: peer.id, timeout: value == 0 ? nil : value).start() + let _ = strongSelf.context.engine.peers.setChatMessageAutoremoveTimeoutInteractively(peerId: peer.id, timeout: value == 0 ? nil : value).start() } }) strongSelf.present(controller, in: .window(.root)) @@ -6511,7 +6511,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - strongSelf.reportIrrelvantGeoDisposable = (TelegramCore.reportPeer(account: strongSelf.context.account, peerId: peerId, reason: .irrelevantLocation, message: "") + strongSelf.reportIrrelvantGeoDisposable = (strongSelf.context.engine.peers.reportPeer(peerId: peerId, reason: .irrelevantLocation, message: "") |> deliverOnMainQueue).start(completed: { [weak self] in if let strongSelf = self { strongSelf.reportIrrelvantGeoNoticePromise.set(.single(true)) @@ -7111,7 +7111,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if case let .peer(peerId) = self.chatLocation, peerId.namespace == Namespaces.Peer.SecretChat, self.screenCaptureManager == nil { self.screenCaptureManager = ScreenCaptureDetectionManager(check: { [weak self] in if let strongSelf = self, strongSelf.canReadHistoryValue, strongSelf.traceVisibility() { - let _ = addSecretChatMessageScreenshot(account: strongSelf.context.account, peerId: peerId).start() + let _ = strongSelf.context.engine.messages.addSecretChatMessageScreenshot(peerId: peerId).start() return true } else { return false @@ -11312,7 +11312,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let user = self.presentationInterfaceState.renderedPeer?.peer as? TelegramUser, user.botInfo != nil { restartBot = true } - self.editMessageDisposable.set((requestUpdatePeerIsBlocked(account: self.context.account, peerId: peerId, isBlocked: false) + self.editMessageDisposable.set((self.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peerId, isBlocked: false) |> afterDisposed({ [weak self] in Queue.mainQueue().async { unblockingPeer.set(false) @@ -11382,7 +11382,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - let _ = requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: true).start() + let _ = strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).start() if let _ = chatPeer as? TelegramSecretChat { let _ = (strongSelf.context.account.postbox.transaction { transaction in terminateSecretChat(transaction: transaction, peerId: chatPeer.id, requestRemoteHistoryRemoval: true) @@ -11392,7 +11392,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = removePeerChat(account: strongSelf.context.account, peerId: chatPeer.id, reportChatSpam: reportSpam).start() strongSelf.effectiveNavigationController?.filterController(strongSelf, animated: true) } else if reportSpam { - let _ = TelegramCore.reportPeer(account: strongSelf.context.account, peerId: peer.id, reason: .spam, message: "").start() + let _ = strongSelf.context.engine.peers.reportPeer(peerId: peer.id, reason: .spam, message: "").start() } }) ] as [ActionSheetItem]) @@ -11512,7 +11512,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else { dismissPeerId = peerId } - self.editMessageDisposable.set((dismissPeerStatusOptions(account: self.context.account, peerId: dismissPeerId) + self.editMessageDisposable.set((self.context.engine.peers.dismissPeerStatusOptions(peerId: dismissPeerId) |> afterDisposed({ Queue.mainQueue().async { } @@ -11528,7 +11528,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = removePeerChat(account: self.context.account, peerId: peerId, reportChatSpam: reportChatSpam).start() self.effectiveNavigationController?.popToRoot(animated: true) - let _ = requestUpdatePeerIsBlocked(account: self.context.account, peerId: peerId, isBlocked: true).start() + let _ = self.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peerId, isBlocked: true).start() } private func startBot(_ payload: String?) { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 841fd452d0..d8d38e7f28 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -2746,7 +2746,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD )) self.privacySettings.set(.single(nil) |> then(requestAccountPrivacySettings(account: context.account) |> map(Optional.init))) self.archivedPacks.set(.single(nil) |> then(context.engine.stickers.archivedStickerPacks() |> map(Optional.init))) - self.hasPassport.set(.single(false) |> then(twoStepAuthData(context.account.network) + self.hasPassport.set(.single(false) |> then(context.engine.auth.twoStepAuthData() |> map { value -> Bool in return value.hasSecretValues } @@ -4267,7 +4267,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD let presentationData = strongSelf.presentationData if let peer = peer as? TelegramUser, let _ = peer.botInfo { - strongSelf.activeActionDisposable.set(requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: block).start()) + strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).start()) if !block { let _ = enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: [.message(text: "/start", attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)]).start() if let navigationController = strongSelf.controller?.navigationController as? NavigationController { @@ -4292,12 +4292,12 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD return } - strongSelf.activeActionDisposable.set(requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: true).start()) + strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: true).start()) if deleteChat { let _ = removePeerChat(account: strongSelf.context.account, peerId: strongSelf.peerId, reportChatSpam: reportSpam).start() (strongSelf.controller?.navigationController as? NavigationController)?.popToRoot(animated: true) } else if reportSpam { - let _ = reportPeer(account: strongSelf.context.account, peerId: strongSelf.peerId, reason: .spam, message: "").start() + let _ = strongSelf.context.engine.peers.reportPeer(peerId: strongSelf.peerId, reason: .spam, message: "").start() } deleteSendMessageIntents(peerId: strongSelf.peerId) @@ -4318,7 +4318,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD guard let strongSelf = self else { return } - strongSelf.activeActionDisposable.set(requestUpdatePeerIsBlocked(account: strongSelf.context.account, peerId: peer.id, isBlocked: block).start()) + strongSelf.activeActionDisposable.set(strongSelf.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peer.id, isBlocked: block).start()) })]), in: .window(.root)) } } diff --git a/submodules/TelegramUI/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Sources/ShareExtensionContext.swift index 91507ed685..d3a24f5dfc 100644 --- a/submodules/TelegramUI/Sources/ShareExtensionContext.swift +++ b/submodules/TelegramUI/Sources/ShareExtensionContext.swift @@ -443,7 +443,7 @@ public class ShareRootControllerImpl { let fileExtension = (fileName as NSString).pathExtension var archivePathValue: String? - var otherEntries: [(SSZipEntry, String, ChatHistoryImport.MediaType)] = [] + var otherEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)] = [] var mainFile: TempBoxFile? let appConfiguration = context.currentAppConfiguration.with({ $0 }) @@ -528,7 +528,7 @@ public class ShareRootControllerImpl { } else { let entryFileName = (entryPath as NSString).lastPathComponent if !entryFileName.isEmpty { - let mediaType: ChatHistoryImport.MediaType + let mediaType: TelegramEngine.HistoryImport.MediaType let fullRange = NSRange(entryFileName.startIndex ..< entryFileName.endIndex, in: entryFileName) if photoRegex.firstMatch(in: entryFileName, options: [], range: fullRange) != nil { mediaType = .photo @@ -641,7 +641,7 @@ public class ShareRootControllerImpl { navigationController.viewControllers = [TempController(context: context)] strongSelf.mainWindow?.present(navigationController, on: .root) - let _ = (ChatHistoryImport.getInfo(account: context.account, header: mainFileHeader) + let _ = (context.engine.historyImport.getInfo(header: mainFileHeader) |> deliverOnMainQueue).start(next: { parseInfo in switch parseInfo { case let .group(groupTitle): @@ -695,7 +695,7 @@ public class ShareRootControllerImpl { strongSelf.mainWindow?.present(controller, on: .root) } else { controller.inProgress = true - let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id) + let _ = (context.engine.historyImport.checkPeerImport(peerId: peer.id) |> deliverOnMainQueue).start(next: { result in controller.inProgress = false @@ -846,7 +846,7 @@ public class ShareRootControllerImpl { attemptSelectionImpl = { [weak controller] peer in controller?.inProgress = true - let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id) + let _ = (context.engine.historyImport.checkPeerImport(peerId: peer.id) |> deliverOnMainQueue).start(next: { result in controller?.inProgress = false @@ -921,7 +921,7 @@ public class ShareRootControllerImpl { attemptSelectionImpl = { [weak controller] peer in controller?.inProgress = true - let _ = (ChatHistoryImport.checkPeerImport(account: context.account, peerId: peer.id) + let _ = (context.engine.historyImport.checkPeerImport(peerId: peer.id) |> deliverOnMainQueue).start(next: { result in controller?.inProgress = false diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index 111e3dea81..d02f3014a6 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -904,7 +904,7 @@ public final class OngoingCallContext { if let callId = callId, !statsLogPath.isEmpty, let data = try? Data(contentsOf: URL(fileURLWithPath: statsLogPath)), let dataString = String(data: data, encoding: .utf8) { debugLogValue.set(.single(dataString)) if sendDebugLogs { - let _ = saveCallDebugLog(network: self.account.network, callId: callId, log: dataString).start() + let _ = TelegramEngine(account: self.account).calls.saveCallDebugLog(callId: callId, log: dataString).start() } } } diff --git a/submodules/WatchBridge/Sources/WatchRequestHandlers.swift b/submodules/WatchBridge/Sources/WatchRequestHandlers.swift index d56763ddfd..1796fe97d7 100644 --- a/submodules/WatchBridge/Sources/WatchRequestHandlers.swift +++ b/submodules/WatchBridge/Sources/WatchRequestHandlers.swift @@ -843,7 +843,7 @@ final class WatchPeerSettingsHandler: WatchRequestHandler { if let args = subscription as? TGBridgePeerUpdateNotificationSettingsSubscription, let peerId = makePeerIdFromBridgeIdentifier(args.peerId) { signal = togglePeerMuted(account: context.account, peerId: peerId) } else if let args = subscription as? TGBridgePeerUpdateBlockStatusSubscription, let peerId = makePeerIdFromBridgeIdentifier(args.peerId) { - signal = requestUpdatePeerIsBlocked(account: context.account, peerId: peerId, isBlocked: args.blocked) + signal = context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peerId, isBlocked: args.blocked) } if let signal = signal {