Add Open Homepage intent

This commit is contained in:
Shadowfacts 2021-10-02 11:47:01 -04:00
parent 29e2589d5c
commit 32648808cb
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
8 changed files with 115 additions and 7 deletions

View File

@ -38,6 +38,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
case is OpenURLIntent: case is OpenURLIntent:
return OpenURLIntentHandler() return OpenURLIntentHandler()
case is OpenHomepageIntent:
return OpenHomepageIntentHandler()
default: default:
return nil return nil
} }

View File

@ -47,12 +47,14 @@
<key>INIntentsSupported</key> <key>INIntentsSupported</key>
<array> <array>
<string>OpenURLIntent</string> <string>OpenURLIntent</string>
<string>OpenHomepageIntent</string>
</array> </array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSUserActivityTypes</key> <key>NSUserActivityTypes</key>
<array> <array>
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string> <string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string>
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.homepage</string>
<string>GemtextToHTMLIntent</string> <string>GemtextToHTMLIntent</string>
<string>GemtextToMarkdownIntent</string> <string>GemtextToMarkdownIntent</string>
<string>GetBodyIntent</string> <string>GetBodyIntent</string>

View File

@ -1026,6 +1026,70 @@
<key>INIntentVerb</key> <key>INIntentVerb</key>
<string>Do</string> <string>Do</string>
</dict> </dict>
<dict>
<key>INIntentCategory</key>
<string>generic</string>
<key>INIntentConfigurable</key>
<true/>
<key>INIntentDescription</key>
<string>Open your Homepage in Rocketeer.</string>
<key>INIntentDescriptionID</key>
<string>rDd9Ha</string>
<key>INIntentManagedParameterCombinations</key>
<dict>
<key></key>
<dict>
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
<true/>
<key>INIntentParameterCombinationTitle</key>
<string>Open Homepage</string>
<key>INIntentParameterCombinationTitleID</key>
<string>McBj5E</string>
<key>INIntentParameterCombinationUpdatesLinked</key>
<true/>
</dict>
</dict>
<key>INIntentName</key>
<string>OpenHomepage</string>
<key>INIntentParameterCombinations</key>
<dict>
<key></key>
<dict>
<key>INIntentParameterCombinationIsPrimary</key>
<true/>
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
<true/>
<key>INIntentParameterCombinationTitle</key>
<string>Open Homepage</string>
<key>INIntentParameterCombinationTitleID</key>
<string>TXy1gX</string>
</dict>
</dict>
<key>INIntentResponse</key>
<dict>
<key>INIntentResponseCodes</key>
<array>
<dict>
<key>INIntentResponseCodeName</key>
<string>success</string>
<key>INIntentResponseCodeSuccess</key>
<true/>
</dict>
<dict>
<key>INIntentResponseCodeName</key>
<string>failure</string>
</dict>
</array>
</dict>
<key>INIntentTitle</key>
<string>Open Homepage</string>
<key>INIntentTitleID</key>
<string>O2KzCP</string>
<key>INIntentType</key>
<string>Custom</string>
<key>INIntentVerb</key>
<string>Do</string>
</dict>
</array> </array>
<key>INTypes</key> <key>INTypes</key>
<array> <array>

View File

@ -0,0 +1,16 @@
//
// OpenHomepageIntentHandler.swift
// Gemini-iOS
//
// Created by Shadowfacts on 10/2/21.
//
import Intents
class OpenHomepageIntentHandler: NSObject, OpenHomepageIntentHandling {
func handle(intent: OpenHomepageIntent, completion: @escaping (OpenHomepageIntentResponse) -> Void) {
completion(OpenHomepageIntentResponse(code: .continueInApp, userActivity: .homepage()))
}
}

View File

@ -8,20 +8,25 @@
import Foundation import Foundation
import BrowserCore import BrowserCore
private let type = "space.vaccor.Gemini.activity.browse" private let browseType = "space.vaccor.Gemini.activity.browse"
private let homepageType = "space.vaccor.Gemini.activity.homepage"
private let encoder = PropertyListEncoder() private let encoder = PropertyListEncoder()
private let decoder = PropertyListDecoder() private let decoder = PropertyListDecoder()
extension NSUserActivity { extension NSUserActivity {
static func homepage() -> NSUserActivity {
return NSUserActivity(activityType: homepageType)
}
convenience init(geminiURL url: URL) { convenience init(geminiURL url: URL) {
self.init(activityType: type) self.init(activityType: browseType)
self.userInfo = [ self.userInfo = [
"url": url, "url": url,
] ]
} }
convenience init(navigationManager manager: NavigationManager) { convenience init(navigationManager manager: NavigationManager) {
self.init(activityType: type) self.init(activityType: browseType)
self.userInfo = [ self.userInfo = [
"url": manager.currentURL, "url": manager.currentURL,
] ]
@ -31,15 +36,19 @@ extension NSUserActivity {
} }
var navigationManager: NavigationManager? { var navigationManager: NavigationManager? {
guard activityType == type, guard activityType == browseType,
let data = userInfo?["manager"] as? Data, let data = userInfo?["manager"] as? Data,
let manager = try? decoder.decode(NavigationManager.self, from: data) else { return nil } let manager = try? decoder.decode(NavigationManager.self, from: data) else { return nil }
return manager return manager
} }
var geminiURL: URL? { var geminiURL: URL? {
guard activityType == type, guard activityType == browseType,
let url = userInfo?["url"] as? URL else { return nil } let url = userInfo?["url"] as? URL else { return nil }
return url return url
} }
var isHomepage: Bool {
return activityType == homepageType
}
} }

View File

@ -109,8 +109,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
if let manager = session.stateRestorationActivity?.navigationManager { if let manager = session.stateRestorationActivity?.navigationManager {
// if there's a user activity with a gemini url (e.g., from OpenURLIntentHandler), // if there's a user activity with a gemini url (e.g., from OpenURLIntentHandler),
// navigate the existing manager to that URL // navigate the existing manager to that URL
if let newURL = connectionOptions.userActivities.first?.geminiURL { if let activity = connectionOptions.userActivities.first {
manager.changeURL(newURL) if let newURL = activity.geminiURL {
manager.changeURL(newURL)
} else if activity.isHomepage {
manager.changeURL(Preferences.shared.homepage)
}
} else if connectionOptions.shortcutItem?.type == "home" { } else if connectionOptions.shortcutItem?.type == "home" {
manager.changeURL(Preferences.shared.homepage) manager.changeURL(Preferences.shared.homepage)
} }
@ -126,6 +130,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
return manager return manager
} else if let url = activity.geminiURL { } else if let url = activity.geminiURL {
initialURL = url initialURL = url
} else if activity.isHomepage {
initialURL = Preferences.shared.homepage
} }
} }

View File

@ -70,6 +70,8 @@
D68C1E4A2708A95D002D642B /* GeminiMarkdownRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */; }; D68C1E4A2708A95D002D642B /* GeminiMarkdownRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */; };
D68C1E4B2708A95D002D642B /* GeminiHTMLRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */; }; D68C1E4B2708A95D002D642B /* GeminiHTMLRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */; };
D68C1E4D2708A981002D642B /* HTMLEntities in Frameworks */ = {isa = PBXBuildFile; productRef = D68C1E4C2708A981002D642B /* HTMLEntities */; }; D68C1E4D2708A981002D642B /* HTMLEntities in Frameworks */ = {isa = PBXBuildFile; productRef = D68C1E4C2708A981002D642B /* HTMLEntities */; };
D68C1E512708B276002D642B /* OpenHomepageIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E502708B276002D642B /* OpenHomepageIntentHandler.swift */; };
D68C1E522708B2D3002D642B /* OpenHomepageIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E502708B276002D642B /* OpenHomepageIntentHandler.swift */; };
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A64D25217C6F00348C4B /* Preferences.swift */; }; D691A64E25217C6F00348C4B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A64D25217C6F00348C4B /* Preferences.swift */; };
D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.swift */; }; D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.swift */; };
D69F00AC24BE9DD300E37622 /* GeminiDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */; }; D69F00AC24BE9DD300E37622 /* GeminiDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */; };
@ -375,6 +377,7 @@
D68C1E422707CB69002D642B /* GeminiMarkdownRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRenderer.swift; sourceTree = "<group>"; }; D68C1E422707CB69002D642B /* GeminiMarkdownRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRenderer.swift; sourceTree = "<group>"; };
D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiHTMLRendererTests.swift; sourceTree = "<group>"; }; D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiHTMLRendererTests.swift; sourceTree = "<group>"; };
D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRendererTests.swift; sourceTree = "<group>"; }; D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRendererTests.swift; sourceTree = "<group>"; };
D68C1E502708B276002D642B /* OpenHomepageIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHomepageIntentHandler.swift; sourceTree = "<group>"; };
D691A64D25217C6F00348C4B /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; }; D691A64D25217C6F00348C4B /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
D691A66625217FD800348C4B /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; }; D691A66625217FD800348C4B /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; };
D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiDataTask.swift; sourceTree = "<group>"; }; D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiDataTask.swift; sourceTree = "<group>"; };
@ -667,6 +670,7 @@
children = ( children = (
D68C1DFF2703EA13002D642B /* UserActivities.swift */, D68C1DFF2703EA13002D642B /* UserActivities.swift */,
D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */, D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */,
D68C1E502708B276002D642B /* OpenHomepageIntentHandler.swift */,
); );
path = Intents; path = Intents;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1260,6 +1264,7 @@
D68C1E3B2707BF25002D642B /* GetStatusIntentHandler.swift in Sources */, D68C1E3B2707BF25002D642B /* GetStatusIntentHandler.swift in Sources */,
D68C1E312706150E002D642B /* Intents.intentdefinition in Sources */, D68C1E312706150E002D642B /* Intents.intentdefinition in Sources */,
D68C1E392707A1E5002D642B /* GetBodyIntentHandler.swift in Sources */, D68C1E392707A1E5002D642B /* GetBodyIntentHandler.swift in Sources */,
D68C1E522708B2D3002D642B /* OpenHomepageIntentHandler.swift in Sources */,
D68C1E3D2707C002002D642B /* GetMetaIntentHandler.swift in Sources */, D68C1E3D2707C002002D642B /* GetMetaIntentHandler.swift in Sources */,
D68C1E3F2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift in Sources */, D68C1E3F2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift in Sources */,
D68C1E28270614F9002D642B /* IntentHandler.swift in Sources */, D68C1E28270614F9002D642B /* IntentHandler.swift in Sources */,
@ -1291,6 +1296,7 @@
D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */, D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */,
D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */, D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */,
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */, D691A64E25217C6F00348C4B /* Preferences.swift in Sources */,
D68C1E512708B276002D642B /* OpenHomepageIntentHandler.swift in Sources */,
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */, D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -14,6 +14,8 @@ class IntentHandler: INExtension {
// we also need to support extension-based handling because in-app handling isn't support <iOS 14 // we also need to support extension-based handling because in-app handling isn't support <iOS 14
case is OpenURLIntent: case is OpenURLIntent:
return OpenURLIntentHandler() return OpenURLIntentHandler()
case is OpenHomepageIntent:
return OpenHomepageIntentHandler()
case is MakeRequestIntent: case is MakeRequestIntent:
return MakeRequestIntentHandler() return MakeRequestIntentHandler()