diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift index 9f872fef59..00f1db00ca 100644 --- a/submodules/ShareController/Sources/ShareController.swift +++ b/submodules/ShareController/Sources/ShareController.swift @@ -426,7 +426,7 @@ public final class ShareController: ViewController { return } strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: title, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - }, externalShare: self.externalShare, immediateExternalShare: self.immediateExternalShare) + }, externalShare: self.externalShare, immediateExternalShare: self.immediateExternalShare, immediatePeerId: self.immediatePeerId) self.controllerNode.dismiss = { [weak self] shared in self?.presentingViewController?.dismiss(animated: false, completion: nil) self?.dismissed?(shared) @@ -704,15 +704,12 @@ public final class ShareController: ViewController { } self.displayNodeDidLoad() - if let _ = self.immediatePeerId { - } else { - self.peersDisposable.set((self.peers.get() - |> deliverOnMainQueue).start(next: { [weak self] next in - if let strongSelf = self { - strongSelf.controllerNode.updatePeers(account: strongSelf.currentAccount, switchableAccounts: strongSelf.switchableAccounts, peers: next.0, accountPeer: next.1, defaultAction: strongSelf.defaultAction) - } - })) - } + self.peersDisposable.set((self.peers.get() + |> deliverOnMainQueue).start(next: { [weak self] next in + if let strongSelf = self { + strongSelf.controllerNode.updatePeers(account: strongSelf.currentAccount, switchableAccounts: strongSelf.switchableAccounts, peers: next.0, accountPeer: next.1, defaultAction: strongSelf.defaultAction) + } + })) self._ready.set(self.controllerNode.ready.get()) } @@ -827,31 +824,23 @@ public final class ShareController: ViewController { return (resultPeers, accountPeer) } }) - if let immediatePeerId = self.immediatePeerId { - self.sendImmediately(peerId: immediatePeerId) - } else { - self.peersDisposable.set((self.peers.get() - |> deliverOnMainQueue).start(next: { [weak self] next in - if let strongSelf = self { - strongSelf.controllerNode.updatePeers(account: strongSelf.currentAccount, switchableAccounts: strongSelf.switchableAccounts, peers: next.0, accountPeer: next.1, defaultAction: strongSelf.defaultAction) - - if animateIn { - strongSelf.readyDisposable.set((strongSelf.controllerNode.ready.get() - |> filter({ $0 }) - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] _ in - guard let strongSelf = self else { - return - } - strongSelf.controllerNode.animateIn() - })) - } + self.peersDisposable.set((self.peers.get() + |> deliverOnMainQueue).start(next: { [weak self] next in + if let strongSelf = self { + strongSelf.controllerNode.updatePeers(account: strongSelf.currentAccount, switchableAccounts: strongSelf.switchableAccounts, peers: next.0, accountPeer: next.1, defaultAction: strongSelf.defaultAction) + + if animateIn { + strongSelf.readyDisposable.set((strongSelf.controllerNode.ready.get() + |> filter({ $0 }) + |> take(1) + |> deliverOnMainQueue).start(next: { [weak self] _ in + guard let strongSelf = self else { + return + } + strongSelf.controllerNode.animateIn() + })) } - })) - } - } - - private func sendImmediately(peerId: PeerId) { - self.controllerNode.send(peerId: peerId) + } + })) } } diff --git a/submodules/ShareController/Sources/ShareControllerNode.swift b/submodules/ShareController/Sources/ShareControllerNode.swift index 1d6daedee1..fc0323a2c9 100644 --- a/submodules/ShareController/Sources/ShareControllerNode.swift +++ b/submodules/ShareController/Sources/ShareControllerNode.swift @@ -31,6 +31,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate private var presentationData: PresentationData private let externalShare: Bool private let immediateExternalShare: Bool + private var immediatePeerId: PeerId? private let defaultAction: ShareControllerAction? private let requestLayout: (ContainedViewLayoutTransition) -> Void @@ -75,11 +76,12 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate private var hapticFeedback: HapticFeedback? - init(sharedContext: SharedAccountContext, defaultAction: ShareControllerAction?, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, presentError: @escaping (String?, String) -> Void, externalShare: Bool, immediateExternalShare: Bool) { + init(sharedContext: SharedAccountContext, defaultAction: ShareControllerAction?, requestLayout: @escaping (ContainedViewLayoutTransition) -> Void, presentError: @escaping (String?, String) -> Void, externalShare: Bool, immediateExternalShare: Bool, immediatePeerId: PeerId?) { self.sharedContext = sharedContext self.presentationData = sharedContext.currentPresentationData.with { $0 } self.externalShare = externalShare self.immediateExternalShare = immediateExternalShare + self.immediatePeerId = immediatePeerId self.presentError = presentError self.defaultAction = defaultAction @@ -151,7 +153,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate } super.init() - + self.controllerInteraction = ShareControllerInteraction(togglePeer: { [weak self] peer, search in if let strongSelf = self { var added = false @@ -642,6 +644,17 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate return } + if let peerId = self.immediatePeerId { + self.immediatePeerId = nil + let _ = (account.postbox.transaction { transaction -> RenderedPeer? in + return transaction.getPeer(peerId).flatMap(RenderedPeer.init(peer:)) + } |> deliverOnMainQueue).start(next: { [weak self] peer in + if let strongSelf = self, let peer = peer { + strongSelf.controllerInteraction?.togglePeer(peer, true) + } + }) + } + let animated = self.peersContentNode == nil let peersContentNode = SharePeersContainerNode(sharedContext: self.sharedContext, account: account, switchableAccounts: switchableAccounts, theme: self.presentationData.theme, strings: self.presentationData.strings, nameDisplayOrder: self.presentationData.nameDisplayOrder, peers: peers, accountPeer: accountPeer, controllerInteraction: self.controllerInteraction!, externalShare: self.externalShare, switchToAnotherAccount: { [weak self] in self?.switchToAnotherAccount?() diff --git a/submodules/TelegramIntents/Sources/TelegramIntents.swift b/submodules/TelegramIntents/Sources/TelegramIntents.swift index 8d8549eabd..b6eca44c5b 100644 --- a/submodules/TelegramIntents/Sources/TelegramIntents.swift +++ b/submodules/TelegramIntents/Sources/TelegramIntents.swift @@ -181,9 +181,13 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou } let interaction = INInteraction(intent: intent, response: nil) interaction.direction = .outgoing - interaction.identifier = "sendMessage_\(account.peerId.toInt64())_\(peer.id.toInt64)" + interaction.identifier = "sendMessage_\(account.peerId.toInt64())_\(peer.id.toInt64())" interaction.groupIdentifier = "sendMessage_\(subject.toString())_\(account.peerId.toInt64())" - interaction.donate() + interaction.donate { error in + if let error = error { + print(error) + } + } } }) } @@ -191,7 +195,7 @@ public func donateSendMessageIntent(account: Account, sharedContext: SharedAccou public func deleteSendMessageIntents(account: Account, peerId: PeerId) { if #available(iOS 10.0, *) { - INInteraction.delete(with: ["sendMessage_\(account.peerId.toInt64())_\(peerId.toInt64)"]) + INInteraction.delete(with: ["sendMessage_\(account.peerId.toInt64())_\(peerId.toInt64())"]) } } diff --git a/submodules/TelegramUI/TelegramUI/AppDelegate.swift b/submodules/TelegramUI/TelegramUI/AppDelegate.swift index a2ef045366..d7942cd458 100644 --- a/submodules/TelegramUI/TelegramUI/AppDelegate.swift +++ b/submodules/TelegramUI/TelegramUI/AppDelegate.swift @@ -1199,7 +1199,7 @@ final class SharedApplicationContext { self.logoutDisposable.set((self.sharedContextPromise.get() |> take(1) - |> mapToSignal { sharedContext -> Signal, NoError> in + |> mapToSignal { sharedContext -> Signal<(AccountManager, Set), NoError> in return sharedContext.sharedContext.activeAccounts |> map { _, accounts, _ -> Set in return Set(accounts.map { $0.1.peerId }) @@ -1210,10 +1210,27 @@ final class SharedApplicationContext { } return updated } - }).start(next: { loggedOutAccountPeerIds in + |> map { loggedOutAccountPeerIds -> (AccountManager, Set) in + return (sharedContext.sharedContext.accountManager, loggedOutAccountPeerIds) + } + }).start(next: { [weak self] accountManager, loggedOutAccountPeerIds in + guard let strongSelf = self else { + return + } for peerId in loggedOutAccountPeerIds { deleteAllSendMessageIntents(accountPeerId: peerId) } + + let _ = (updateIntentsSettingsInteractively(accountManager: accountManager) { current in + var updated = current + for peerId in loggedOutAccountPeerIds { + if peerId == updated.account { + updated = updated.withUpdatedAccount(nil) + break + } + } + return updated + }).start() })) self.watchCommunicationManagerPromise.set(watchCommunicationManager(context: self.context.get() |> flatMap { WatchCommunicationManagerContext(context: $0.context) }, allowBackgroundTimeExtension: { timeout in diff --git a/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift b/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift index 283192e7a9..7d99cfd0f1 100644 --- a/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift +++ b/submodules/TelegramUI/TelegramUI/ShareExtensionContext.swift @@ -198,6 +198,16 @@ public class ShareRootControllerImpl { globalInternalContext = internalContext } + var immediatePeerId: PeerId? + if #available(iOS 13.2, *), let sendMessageIntent = self.getExtensionContext()?.intent as? INSendMessageIntent { + if let contact = sendMessageIntent.recipients?.first, let handle = contact.customIdentifier, handle.hasPrefix("tg") { + let string = handle.suffix(from: handle.index(handle.startIndex, offsetBy: 2)) + if let userId = Int32(string) { + immediatePeerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) + } + } + } + let account: Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> = internalContext.sharedContext.accountManager.transaction { transaction -> (SharedAccountContextImpl, LoggingSettings) in return (internalContext.sharedContext, transaction.getSharedData(SharedDataKeys.loggingSettings) as? LoggingSettings ?? LoggingSettings.defaultSettings) } @@ -208,24 +218,36 @@ public class ShareRootControllerImpl { Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData - return combineLatest(sharedContext.activeAccountsWithInfo, accountManager.transaction { transaction -> Set in - return Set(transaction.getRecords().map { record in + return combineLatest(sharedContext.activeAccountsWithInfo, accountManager.transaction { transaction -> (Set, PeerId?) in + let accountRecords = Set(transaction.getRecords().map { record in return record.id }) + let intentsSettings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.intentsSettings) as? IntentsSettings ?? IntentsSettings.defaultSettings + return (accountRecords, intentsSettings.account) }) |> castError(ShareAuthorizationError.self) |> take(1) - |> mapToSignal { primaryAndAccounts, validAccountIds -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in + |> mapToSignal { primaryAndAccounts, validAccountIdsAndIntentsAccountId -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in var (maybePrimary, accounts) = primaryAndAccounts + let (validAccountIds, intentsAccountId) = validAccountIdsAndIntentsAccountId for i in (0 ..< accounts.count).reversed() { if !validAccountIds.contains(accounts[i].account.id) { accounts.remove(at: i) } } + if let _ = immediatePeerId, let intentsAccountId = intentsAccountId { + for account in accounts { + if account.peer.id == intentsAccountId { + maybePrimary = account.account.id + } + } + } + guard let primary = maybePrimary, validAccountIds.contains(primary) else { return .fail(.unauthorized) } + guard let info = accounts.first(where: { $0.account.id == primary }) else { return .fail(.unauthorized) } @@ -294,17 +316,7 @@ public class ShareRootControllerImpl { } |> then(.single(.done)) } - - var immediatePeerId: PeerId? - if #available(iOS 13.0, *), let sendMessageIntent = self?.getExtensionContext()?.intent as? INSendMessageIntent { - if let contact = sendMessageIntent.recipients?.first, let handle = contact.customIdentifier, handle.hasPrefix("tg") { - let string = handle.suffix(from: handle.index(handle.startIndex, offsetBy: 2)) - if let userId = Int32(string) { - immediatePeerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) - } - } - } - + let shareController = ShareController(context: context, subject: .fromExternal({ peerIds, additionalText, account in if let strongSelf = self, let inputItems = strongSelf.getExtensionContext()?.inputItems, !inputItems.isEmpty, !peerIds.isEmpty { let rawSignals = TGItemProviderSignals.itemSignals(forInputItems: inputItems)! diff --git a/submodules/TelegramUIPreferences/Sources/IntentsSettings.swift b/submodules/TelegramUIPreferences/Sources/IntentsSettings.swift index aeebdbe011..b7ba32db2b 100644 --- a/submodules/TelegramUIPreferences/Sources/IntentsSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/IntentsSettings.swift @@ -27,7 +27,7 @@ public struct IntentsSettings: PreferencesEntry, Equatable { } public init(decoder: PostboxDecoder) { - self.initiallyReset = decoder.decodeBoolForKey("initiallyReset_v2", orElse: false) + self.initiallyReset = decoder.decodeBoolForKey("initiallyReset_v1", orElse: false) self.account = decoder.decodeOptionalInt64ForKey("account").flatMap { PeerId($0) } self.contacts = decoder.decodeBoolForKey("contacts", orElse: true) self.privateChats = decoder.decodeBoolForKey("privateChats", orElse: false) @@ -37,7 +37,7 @@ public struct IntentsSettings: PreferencesEntry, Equatable { } public func encode(_ encoder: PostboxEncoder) { - encoder.encodeBool(self.initiallyReset, forKey: "initiallyReset_v2") + encoder.encodeBool(self.initiallyReset, forKey: "initiallyReset_v1") if let account = self.account { encoder.encodeInt64(account.toInt64(), forKey: "account") } else { @@ -62,7 +62,7 @@ public struct IntentsSettings: PreferencesEntry, Equatable { return lhs.initiallyReset == rhs.initiallyReset && lhs.account == rhs.account && lhs.contacts == rhs.contacts && lhs.privateChats == rhs.privateChats && lhs.savedMessages == rhs.savedMessages && lhs.groups == rhs.groups && lhs.onlyShared == rhs.onlyShared } - public func withUpdatedAccount(_ account: PeerId) -> IntentsSettings { + public func withUpdatedAccount(_ account: PeerId?) -> IntentsSettings { return IntentsSettings(initiallyReset: self.initiallyReset, account: account, contacts: self.contacts, privateChats: self.privateChats, savedMessages: self.savedMessages, groups: self.groups, onlyShared: self.onlyShared) }