mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 11:23:48 +00:00
Improve Share Suggestion execution flow
This commit is contained in:
parent
45224e6e96
commit
5e620dc318
@ -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)
|
||||
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()
|
||||
}))
|
||||
}
|
||||
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)
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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?()
|
||||
|
@ -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())"])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1199,7 +1199,7 @@ final class SharedApplicationContext {
|
||||
|
||||
self.logoutDisposable.set((self.sharedContextPromise.get()
|
||||
|> take(1)
|
||||
|> mapToSignal { sharedContext -> Signal<Set<PeerId>, NoError> in
|
||||
|> mapToSignal { sharedContext -> Signal<(AccountManager, Set<PeerId>), NoError> in
|
||||
return sharedContext.sharedContext.activeAccounts
|
||||
|> map { _, accounts, _ -> Set<PeerId> 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<PeerId>) 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
|
||||
|
@ -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<AccountRecordId> in
|
||||
return Set(transaction.getRecords().map { record in
|
||||
return combineLatest(sharedContext.activeAccountsWithInfo, accountManager.transaction { transaction -> (Set<AccountRecordId>, 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)
|
||||
}
|
||||
@ -295,16 +317,6 @@ 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)!
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user