mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-01 16:06:59 +00:00
Donate send message intents when posting from share controller
Clear donated send message intents on logout
This commit is contained in:
parent
f3120ee918
commit
8ca47c3aef
23
submodules/AppIntents/BUCK
Normal file
23
submodules/AppIntents/BUCK
Normal file
@ -0,0 +1,23 @@
|
||||
load("//Config:buck_rule_macros.bzl", "static_library")
|
||||
|
||||
static_library(
|
||||
name = "AppIntents",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
deps = [
|
||||
"//submodules/TelegramCore:TelegramCore#shared",
|
||||
"//submodules/SyncCore:SyncCore#shared",
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared",
|
||||
"//submodules/Display:Display#shared",
|
||||
"//submodules/AccountContext:AccountContext",
|
||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||
"//submodules/AvatarNode:AvatarNode",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
],
|
||||
weak_frameworks = [
|
||||
"Intents",
|
||||
],
|
||||
)
|
22
submodules/AppIntents/Info.plist
Normal file
22
submodules/AppIntents/Info.plist
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
</dict>
|
||||
</plist>
|
67
submodules/AppIntents/Sources/AppIntents.swift
Normal file
67
submodules/AppIntents/Sources/AppIntents.swift
Normal file
@ -0,0 +1,67 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Intents
|
||||
import Display
|
||||
import Postbox
|
||||
import TelegramCore
|
||||
import SyncCore
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import AvatarNode
|
||||
import AccountContext
|
||||
|
||||
public func donateSendMessageIntent(account: Account, sharedContext: SharedAccountContext, peerIds: [PeerId]) {
|
||||
if #available(iOSApplicationExtension 13.2, iOS 13.2, *) {
|
||||
let _ = (account.postbox.transaction { transaction -> [Peer] in
|
||||
var peers: [Peer] = []
|
||||
for peerId in peerIds {
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser && peerId != account.peerId, let peer = transaction.getPeer(peerId) {
|
||||
peers.append(peer)
|
||||
}
|
||||
}
|
||||
return peers
|
||||
}
|
||||
|> mapToSignal { peers -> Signal<[(Peer, UIImage?)], NoError> in
|
||||
var signals: [Signal<(Peer, UIImage?), NoError>] = []
|
||||
for peer in peers {
|
||||
let peerAndAvatar = (peerAvatarImage(account: account, peer: peer, authorOfMessage: nil, representation: peer.smallProfileImage, round: false) ?? .single(nil))
|
||||
|> map { avatarImage in
|
||||
return (peer, avatarImage)
|
||||
}
|
||||
signals.append(peerAndAvatar)
|
||||
}
|
||||
return combineLatest(signals)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { peers in
|
||||
for (peer, avatarImage) in peers {
|
||||
guard let peer = peer as? TelegramUser, peer.botInfo == nil && !peer.flags.contains(.isSupport) else {
|
||||
continue
|
||||
}
|
||||
let presentationData = sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let recipientHandle = INPersonHandle(value: "tg\(peer.id.id)", type: .unknown)
|
||||
var nameComponents = PersonNameComponents()
|
||||
nameComponents.givenName = peer.firstName
|
||||
nameComponents.familyName = peer.lastName
|
||||
|
||||
let displayTitle = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||
let recipient = INPerson(personHandle: recipientHandle, nameComponents: nameComponents, displayName: displayTitle, image: nil, contactIdentifier: nil, customIdentifier: "tg\(peer.id.id)")
|
||||
|
||||
let intent = INSendMessageIntent(recipients: [recipient], content: nil, speakableGroupName: INSpeakableString(spokenPhrase: displayTitle), conversationIdentifier: "tg\(peer.id.id)", serviceName: nil, sender: nil)
|
||||
if let avatarImage = avatarImage, let avatarImageData = avatarImage.jpegData(compressionQuality: 0.8) {
|
||||
intent.setImage(INImage(imageData: avatarImageData), forParameterNamed: \.groupName)
|
||||
}
|
||||
let interaction = INInteraction(intent: intent, response: nil)
|
||||
interaction.direction = .outgoing
|
||||
interaction.groupIdentifier = "sendMessage_\(account.peerId.toInt64())"
|
||||
interaction.donate()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public func deleteAllSendMessageIntents(accountPeerId: PeerId) {
|
||||
if #available(iOS 10.0, *) {
|
||||
INInteraction.delete(with: "sendMessage_\(accountPeerId.toInt64())")
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ static_library(
|
||||
"//submodules/ActivityIndicator:ActivityIndicator",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
"//submodules/AppIntents:AppIntents",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
|
@ -8,6 +8,7 @@ import TelegramCore
|
||||
import SyncCore
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import AppIntents
|
||||
|
||||
enum ShareState {
|
||||
case preparing
|
||||
@ -26,6 +27,7 @@ func openExternalShare(state: () -> Signal<ShareExternalState, NoError>) {
|
||||
|
||||
final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
||||
private let sharedContext: SharedAccountContext
|
||||
private var account: Account?
|
||||
private var presentationData: PresentationData
|
||||
private let externalShare: Bool
|
||||
private let immediateExternalShare: Bool
|
||||
@ -537,6 +539,10 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
peerIds = self.controllerInteraction!.selectedPeers.map { $0.peerId }
|
||||
}
|
||||
|
||||
if let account = self.account {
|
||||
donateSendMessageIntent(account: account, sharedContext: self.sharedContext, peerIds: peerIds)
|
||||
}
|
||||
|
||||
if let signal = self.share?(self.inputFieldNode.text, peerIds) {
|
||||
self.transitionToContentNode(ShareLoadingContainerNode(theme: self.presentationData.theme, forceNativeAppearance: true), fastOut: true)
|
||||
let timestamp = CACurrentMediaTime()
|
||||
@ -629,6 +635,8 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
|
||||
func updatePeers(account: Account, switchableAccounts: [AccountWithInfo], peers: [(RenderedPeer, PeerPresence?)], accountPeer: Peer, defaultAction: ShareControllerAction?) {
|
||||
self.account = account
|
||||
|
||||
if let peersContentNode = self.peersContentNode, peersContentNode.accountPeer.id == accountPeer.id {
|
||||
peersContentNode.peersValue.set(.single(peers))
|
||||
return
|
||||
|
@ -197,6 +197,7 @@ framework(
|
||||
"//submodules/AppLock:AppLock",
|
||||
"//submodules/NotificationsPresentationData:NotificationsPresentationData",
|
||||
"//submodules/UrlWhitelist:UrlWhitelist",
|
||||
"//submodules/AppIntents:AppIntents",
|
||||
],
|
||||
frameworks = [
|
||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||
|
@ -33,6 +33,7 @@ import WalletCore
|
||||
import OpenSSLEncryptionProvider
|
||||
import AppLock
|
||||
import PresentationDataUtils
|
||||
import AppIntents
|
||||
|
||||
#if canImport(BackgroundTasks)
|
||||
import BackgroundTasks
|
||||
@ -179,6 +180,8 @@ final class SharedApplicationContext {
|
||||
private let authContext = Promise<UnauthorizedApplicationContext?>()
|
||||
private let authContextDisposable = MetaDisposable()
|
||||
|
||||
private let logoutDisposable = MetaDisposable()
|
||||
|
||||
private let openChatWhenReadyDisposable = MetaDisposable()
|
||||
private let openUrlWhenReadyDisposable = MetaDisposable()
|
||||
|
||||
@ -1155,7 +1158,8 @@ final class SharedApplicationContext {
|
||||
}
|
||||
|> take(1)
|
||||
|> timeout(4.0, queue: .mainQueue(), alternate: .complete())
|
||||
|> deliverOnMainQueue).start(completed: { authContextValue.rootController.view.endEditing(true)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
authContextValue.rootController.view.endEditing(true)
|
||||
authContextValue.rootController.dismiss()
|
||||
})
|
||||
} else {
|
||||
@ -1174,12 +1178,32 @@ final class SharedApplicationContext {
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { _ in
|
||||
statusController.dismiss()
|
||||
self.mainWindow.present(context.rootController, on: .root) }))
|
||||
self.mainWindow.present(context.rootController, on: .root)
|
||||
}))
|
||||
} else {
|
||||
authContextReadyDisposable.set(nil)
|
||||
}
|
||||
}))
|
||||
|
||||
self.logoutDisposable.set((self.sharedContextPromise.get()
|
||||
|> take(1)
|
||||
|> mapToSignal { sharedContext -> Signal<Set<PeerId>, NoError> in
|
||||
return sharedContext.sharedContext.activeAccounts
|
||||
|> map { _, accounts, _ -> Set<PeerId> in
|
||||
return Set(accounts.map { $0.1.peerId })
|
||||
}
|
||||
|> reduceLeft(value: Set<PeerId>()) { current, updated, emit in
|
||||
if !current.isEmpty {
|
||||
emit(current.subtracting(current.intersection(updated)))
|
||||
}
|
||||
return updated
|
||||
}
|
||||
}).start(next: { loggedOutAccountPeerIds in
|
||||
for peerId in loggedOutAccountPeerIds {
|
||||
deleteAllSendMessageIntents(accountPeerId: peerId)
|
||||
}
|
||||
}))
|
||||
|
||||
self.watchCommunicationManagerPromise.set(watchCommunicationManager(context: self.context.get() |> flatMap { WatchCommunicationManagerContext(context: $0.context) }, allowBackgroundTimeExtension: { timeout in
|
||||
let _ = (self.sharedContextPromise.get()
|
||||
|> take(1)).start(next: { sharedContext in
|
||||
|
@ -55,6 +55,7 @@ import LocalizedPeerData
|
||||
import PhoneNumberFormat
|
||||
import SettingsUI
|
||||
import UrlWhitelist
|
||||
import AppIntents
|
||||
|
||||
public enum ChatControllerPeekActions {
|
||||
case standard
|
||||
@ -2798,7 +2799,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
})
|
||||
|
||||
strongSelf.donateSendMessageIntent()
|
||||
donateSendMessageIntent(account: strongSelf.context.account, sharedContext: strongSelf.context.sharedContext, peerIds: [peerId])
|
||||
}
|
||||
}
|
||||
|
||||
@ -5994,7 +5995,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
})
|
||||
|
||||
self.donateSendMessageIntent()
|
||||
donateSendMessageIntent(account: self.context.account, sharedContext: self.context.sharedContext, peerIds: [peerId])
|
||||
} else {
|
||||
let mode: ChatScheduleTimeControllerMode
|
||||
if peerId == self.context.account.peerId {
|
||||
@ -8067,44 +8068,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
})
|
||||
}
|
||||
|
||||
private func donateSendMessageIntent() {
|
||||
guard case let .peer(peerId) = self.chatLocation, peerId.namespace == Namespaces.Peer.CloudUser && peerId != self.context.account.peerId else {
|
||||
return
|
||||
}
|
||||
if #available(iOSApplicationExtension 13.2, iOS 13.2, *) {
|
||||
let _ = (self.context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> mapToSignal { peer -> Signal<(Peer, UIImage?), NoError> in
|
||||
let avatarImage = peerAvatarImage(account: self.context.account, peer: peer, authorOfMessage: nil, representation: peer.smallProfileImage, round: false) ?? .single(nil)
|
||||
return avatarImage
|
||||
|> map { avatarImage in
|
||||
return (peer, avatarImage)
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer, avatarImage in
|
||||
if let strongSelf = self, let peer = peer as? TelegramUser, peer.botInfo == nil && !peer.flags.contains(.isSupport) {
|
||||
let recipientHandle = INPersonHandle(value: "tg\(peerId.id)", type: .unknown)
|
||||
var nameComponents = PersonNameComponents()
|
||||
nameComponents.givenName = peer.firstName
|
||||
nameComponents.familyName = peer.lastName
|
||||
let displayTitle = peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)
|
||||
let recipient = INPerson(personHandle: recipientHandle, nameComponents: nameComponents, displayName: displayTitle, image: nil, contactIdentifier: nil, customIdentifier: "tg\(peerId.id)")
|
||||
let intent = INSendMessageIntent(recipients: [recipient], content: nil, speakableGroupName: INSpeakableString(spokenPhrase: displayTitle), conversationIdentifier: "tg\(peerId.id)", serviceName: nil, sender: nil)
|
||||
if #available(iOS 12.0, *), let avatarImage = avatarImage, let avatarImageData = avatarImage.jpegData(compressionQuality: 0.8) {
|
||||
intent.setImage(INImage(imageData: avatarImageData), forParameterNamed: \.groupName)
|
||||
}
|
||||
let interaction = INInteraction(intent: intent, response: nil)
|
||||
interaction.direction = .outgoing
|
||||
interaction.groupIdentifier = "sendMessage_\(strongSelf.context.account.peerId.toInt64())"
|
||||
interaction.donate { error in
|
||||
if let error = error {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func updateReminderActivity() {
|
||||
if self.isReminderActivityEnabled && false {
|
||||
if #available(iOS 9.0, *) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user