Add the ability to specify folder in Add Feed shortcut
This commit is contained in:
parent
b1668d6a62
commit
af16731ecd
|
@ -455,6 +455,10 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
|||
return ensureFolder(with: folderName)
|
||||
}
|
||||
|
||||
public func findFolder(withDisplayName displayName: String) -> Folder? {
|
||||
return folders?.first(where: { $0.nameForDisplay == displayName })
|
||||
}
|
||||
|
||||
func newFeed(with opmlFeedSpecifier: RSOPMLFeedSpecifier) -> Feed {
|
||||
let feedURL = opmlFeedSpecifier.feedURL
|
||||
let metadata = feedMetadata(feedURL: feedURL, feedID: feedURL)
|
||||
|
|
|
@ -58,6 +58,10 @@ public final class AccountManager: UnreadCountProvider {
|
|||
return sortByName(activeAccounts)
|
||||
}
|
||||
|
||||
public func findActiveAccount(forDisplayName displayName: String) -> Account? {
|
||||
return AccountManager.shared.activeAccounts.first(where: { $0.nameForDisplay == displayName })
|
||||
}
|
||||
|
||||
public var refreshInProgress: Bool {
|
||||
for account in activeAccounts {
|
||||
if account.refreshInProgress {
|
||||
|
|
|
@ -10,7 +10,7 @@ import Intents
|
|||
import Account
|
||||
|
||||
public class AddFeedIntentHandler: NSObject, AddFeedIntentHandling {
|
||||
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
DispatchQueue.main.sync {
|
||||
|
@ -35,25 +35,85 @@ public class AddFeedIntentHandler: NSObject, AddFeedIntentHandling {
|
|||
|
||||
public func resolveAccountName(for intent: AddFeedIntent, with completion: @escaping (AddFeedAccountNameResolutionResult) -> Void) {
|
||||
guard let accountName = intent.accountName else {
|
||||
completion(.unsupported(forReason: .required))
|
||||
completion(AddFeedAccountNameResolutionResult.notRequired())
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
if AccountManager.shared.findActiveAccount(forDisplayName: accountName) == nil {
|
||||
completion(.unsupported(forReason: .invalid))
|
||||
} else {
|
||||
completion(.success(with: accountName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func provideFolderNameOptions(for intent: AddFeedIntent, with completion: @escaping ([String]?, Error?) -> Void) {
|
||||
DispatchQueue.main.async {
|
||||
guard let accountName = intent.accountName, let account = AccountManager.shared.findActiveAccount(forDisplayName: accountName) else {
|
||||
completion([String](), nil)
|
||||
return
|
||||
}
|
||||
|
||||
let folderNames = account.folders?.map { $0.nameForDisplay }
|
||||
completion(folderNames, nil)
|
||||
}
|
||||
}
|
||||
|
||||
public func resolveFolderName(for intent: AddFeedIntent, with completion: @escaping (AddFeedFolderNameResolutionResult) -> Void) {
|
||||
guard let accountName = intent.accountName, let folderName = intent.folderName else {
|
||||
completion(AddFeedFolderNameResolutionResult.notRequired())
|
||||
return
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
guard let account = AccountManager.shared.findActiveAccount(forDisplayName: accountName) else {
|
||||
completion(.unsupported(forReason: .invalid))
|
||||
return
|
||||
}
|
||||
if account.findFolder(withDisplayName: folderName) == nil {
|
||||
completion(.unsupported(forReason: .invalid))
|
||||
} else {
|
||||
completion(.success(with: folderName))
|
||||
}
|
||||
return
|
||||
}
|
||||
completion(.success(with: accountName))
|
||||
}
|
||||
|
||||
public func handle(intent: AddFeedIntent, completion: @escaping (AddFeedIntentResponse) -> Void) {
|
||||
guard let url = intent.url, let accountName = intent.accountName else {
|
||||
guard let url = intent.url else {
|
||||
completion(AddFeedIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
guard let account = AccountManager.shared.activeAccounts.first(where: { $0.nameForDisplay == accountName }) else {
|
||||
|
||||
let account: Account? = {
|
||||
if let accountName = intent.accountName {
|
||||
return AccountManager.shared.findActiveAccount(forDisplayName: accountName)
|
||||
} else {
|
||||
return AccountManager.shared.sortedActiveAccounts.first
|
||||
}
|
||||
}()
|
||||
|
||||
guard let validAccount = account else {
|
||||
completion(AddFeedIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
|
||||
account.createFeed(url: url.absoluteString, name: nil, container: account) { result in
|
||||
let container: Container? = {
|
||||
if let folderName = intent.folderName {
|
||||
return validAccount.findFolder(withDisplayName: folderName)
|
||||
} else {
|
||||
return validAccount
|
||||
}
|
||||
}()
|
||||
|
||||
guard let validContainer = container else {
|
||||
completion(AddFeedIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
|
||||
validAccount.createFeed(url: url.absoluteString, name: nil, container: validContainer) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(AddFeedIntentResponse(code: .success, userActivity: nil))
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<key>INIntentKeyParameter</key>
|
||||
<string>url</string>
|
||||
<key>INIntentLastParameterTag</key>
|
||||
<integer>3</integer>
|
||||
<integer>4</integer>
|
||||
<key>INIntentManagedParameterCombinations</key>
|
||||
<dict>
|
||||
<key>url,accountName</key>
|
||||
|
@ -40,7 +40,18 @@
|
|||
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationTitle</key>
|
||||
<string>Add${url}to ${accountName}</string>
|
||||
<string>Add ${url} to ${accountName}</string>
|
||||
<key>INIntentParameterCombinationTitleID</key>
|
||||
<string>kaKsEY</string>
|
||||
<key>INIntentParameterCombinationUpdatesLinked</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>url,accountName,folderName</key>
|
||||
<dict>
|
||||
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationTitle</key>
|
||||
<string>Add ${url} to ${folderName} in ${accountName}</string>
|
||||
<key>INIntentParameterCombinationTitleID</key>
|
||||
<string>dkSFD2</string>
|
||||
<key>INIntentParameterCombinationUpdatesLinked</key>
|
||||
|
@ -66,7 +77,7 @@
|
|||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>What is the ${url}you would like add?</string>
|
||||
<string>What is the ${url} you would like add?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>jLLidQ</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
|
@ -158,16 +169,98 @@
|
|||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>required</string>
|
||||
<string>invalid</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>An account name is required.</string>
|
||||
<string>A valid Account Name is required.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>JGkCuS</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterCustomDisambiguation</key>
|
||||
<true/>
|
||||
<key>INIntentParameterDisplayName</key>
|
||||
<string>Folder Name</string>
|
||||
<key>INIntentParameterDisplayNameID</key>
|
||||
<string>zXhMPF</string>
|
||||
<key>INIntentParameterDisplayPriority</key>
|
||||
<integer>3</integer>
|
||||
<key>INIntentParameterMetadata</key>
|
||||
<dict>
|
||||
<key>INIntentParameterMetadataCapitalization</key>
|
||||
<string>Sentences</string>
|
||||
</dict>
|
||||
<key>INIntentParameterName</key>
|
||||
<string>folderName</string>
|
||||
<key>INIntentParameterPromptDialogs</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Primary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>There are ${count} options matching ‘${folderName}’.</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>5CYbGL</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>DisambiguationIntroduction</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>Which one?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>gEzXaM</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>DisambiguationSelection</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>Just to confirm, you wanted ‘${folderName}’?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>k5GTo0</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Confirmation</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INIntentParameterRelationship</key>
|
||||
<dict>
|
||||
<key>INIntentParameterRelationshipParentName</key>
|
||||
<string>accountName</string>
|
||||
<key>INIntentParameterRelationshipPredicateName</key>
|
||||
<string>HasAnyValue</string>
|
||||
</dict>
|
||||
<key>INIntentParameterSupportsDynamicEnumeration</key>
|
||||
<true/>
|
||||
<key>INIntentParameterSupportsResolution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterTag</key>
|
||||
<integer>4</integer>
|
||||
<key>INIntentParameterType</key>
|
||||
<string>String</string>
|
||||
<key>INIntentParameterUnsupportedReasons</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>invalid</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>A valid Folder Name is required.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>ef5kBt</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INIntentResponse</key>
|
||||
<dict>
|
||||
|
|
Loading…
Reference in New Issue