diff --git a/Gemini-iOS/AppDelegate.swift b/Gemini-iOS/AppDelegate.swift index 6ffbbef..6039c0c 100644 --- a/Gemini-iOS/AppDelegate.swift +++ b/Gemini-iOS/AppDelegate.swift @@ -38,6 +38,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { case is OpenURLIntent: return OpenURLIntentHandler() + case is OpenHomepageIntent: + return OpenHomepageIntentHandler() + default: return nil } diff --git a/Gemini-iOS/Info.plist b/Gemini-iOS/Info.plist index 1084fca..22991bf 100644 --- a/Gemini-iOS/Info.plist +++ b/Gemini-iOS/Info.plist @@ -47,12 +47,14 @@ INIntentsSupported OpenURLIntent + OpenHomepageIntent LSRequiresIPhoneOS NSUserActivityTypes $(PRODUCE_BUNDLE_IDENTIFIER).activity.browse + $(PRODUCE_BUNDLE_IDENTIFIER).activity.homepage GemtextToHTMLIntent GemtextToMarkdownIntent GetBodyIntent diff --git a/Gemini-iOS/Intents.intentdefinition b/Gemini-iOS/Intents.intentdefinition index f3d17e0..d94730a 100644 --- a/Gemini-iOS/Intents.intentdefinition +++ b/Gemini-iOS/Intents.intentdefinition @@ -1026,6 +1026,70 @@ INIntentVerb Do + + INIntentCategory + generic + INIntentConfigurable + + INIntentDescription + Open your Homepage in Rocketeer. + INIntentDescriptionID + rDd9Ha + INIntentManagedParameterCombinations + + + + INIntentParameterCombinationSupportsBackgroundExecution + + INIntentParameterCombinationTitle + Open Homepage + INIntentParameterCombinationTitleID + McBj5E + INIntentParameterCombinationUpdatesLinked + + + + INIntentName + OpenHomepage + INIntentParameterCombinations + + + + INIntentParameterCombinationIsPrimary + + INIntentParameterCombinationSupportsBackgroundExecution + + INIntentParameterCombinationTitle + Open Homepage + INIntentParameterCombinationTitleID + TXy1gX + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Open Homepage + INIntentTitleID + O2KzCP + INIntentType + Custom + INIntentVerb + Do + INTypes diff --git a/Gemini-iOS/Intents/OpenHomepageIntentHandler.swift b/Gemini-iOS/Intents/OpenHomepageIntentHandler.swift new file mode 100644 index 0000000..dfae801 --- /dev/null +++ b/Gemini-iOS/Intents/OpenHomepageIntentHandler.swift @@ -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())) + } + +} diff --git a/Gemini-iOS/Intents/UserActivities.swift b/Gemini-iOS/Intents/UserActivities.swift index 017a880..7c33548 100644 --- a/Gemini-iOS/Intents/UserActivities.swift +++ b/Gemini-iOS/Intents/UserActivities.swift @@ -8,20 +8,25 @@ import Foundation 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 decoder = PropertyListDecoder() extension NSUserActivity { + static func homepage() -> NSUserActivity { + return NSUserActivity(activityType: homepageType) + } + convenience init(geminiURL url: URL) { - self.init(activityType: type) + self.init(activityType: browseType) self.userInfo = [ "url": url, ] } convenience init(navigationManager manager: NavigationManager) { - self.init(activityType: type) + self.init(activityType: browseType) self.userInfo = [ "url": manager.currentURL, ] @@ -31,15 +36,19 @@ extension NSUserActivity { } var navigationManager: NavigationManager? { - guard activityType == type, + guard activityType == browseType, let data = userInfo?["manager"] as? Data, let manager = try? decoder.decode(NavigationManager.self, from: data) else { return nil } return manager } var geminiURL: URL? { - guard activityType == type, + guard activityType == browseType, let url = userInfo?["url"] as? URL else { return nil } return url } + + var isHomepage: Bool { + return activityType == homepageType + } } diff --git a/Gemini-iOS/SceneDelegate.swift b/Gemini-iOS/SceneDelegate.swift index c7e3fa1..39834b9 100644 --- a/Gemini-iOS/SceneDelegate.swift +++ b/Gemini-iOS/SceneDelegate.swift @@ -109,8 +109,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { if let manager = session.stateRestorationActivity?.navigationManager { // if there's a user activity with a gemini url (e.g., from OpenURLIntentHandler), // navigate the existing manager to that URL - if let newURL = connectionOptions.userActivities.first?.geminiURL { - manager.changeURL(newURL) + if let activity = connectionOptions.userActivities.first { + if let newURL = activity.geminiURL { + manager.changeURL(newURL) + } else if activity.isHomepage { + manager.changeURL(Preferences.shared.homepage) + } } else if connectionOptions.shortcutItem?.type == "home" { manager.changeURL(Preferences.shared.homepage) } @@ -126,6 +130,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { return manager } else if let url = activity.geminiURL { initialURL = url + } else if activity.isHomepage { + initialURL = Preferences.shared.homepage } } diff --git a/Gemini.xcodeproj/project.pbxproj b/Gemini.xcodeproj/project.pbxproj index db2e0fa..f9d07fd 100644 --- a/Gemini.xcodeproj/project.pbxproj +++ b/Gemini.xcodeproj/project.pbxproj @@ -70,6 +70,8 @@ D68C1E4A2708A95D002D642B /* GeminiMarkdownRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */; }; D68C1E4B2708A95D002D642B /* GeminiHTMLRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */; }; 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 */; }; D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.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 = ""; }; D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiHTMLRendererTests.swift; sourceTree = ""; }; D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRendererTests.swift; sourceTree = ""; }; + D68C1E502708B276002D642B /* OpenHomepageIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenHomepageIntentHandler.swift; sourceTree = ""; }; D691A64D25217C6F00348C4B /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; D691A66625217FD800348C4B /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; }; D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiDataTask.swift; sourceTree = ""; }; @@ -667,6 +670,7 @@ children = ( D68C1DFF2703EA13002D642B /* UserActivities.swift */, D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */, + D68C1E502708B276002D642B /* OpenHomepageIntentHandler.swift */, ); path = Intents; sourceTree = ""; @@ -1260,6 +1264,7 @@ D68C1E3B2707BF25002D642B /* GetStatusIntentHandler.swift in Sources */, D68C1E312706150E002D642B /* Intents.intentdefinition in Sources */, D68C1E392707A1E5002D642B /* GetBodyIntentHandler.swift in Sources */, + D68C1E522708B2D3002D642B /* OpenHomepageIntentHandler.swift in Sources */, D68C1E3D2707C002002D642B /* GetMetaIntentHandler.swift in Sources */, D68C1E3F2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift in Sources */, D68C1E28270614F9002D642B /* IntentHandler.swift in Sources */, @@ -1291,6 +1296,7 @@ D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */, D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */, D691A64E25217C6F00348C4B /* Preferences.swift in Sources */, + D68C1E512708B276002D642B /* OpenHomepageIntentHandler.swift in Sources */, D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/GeminiIntents/IntentHandler.swift b/GeminiIntents/IntentHandler.swift index 7fec199..3de26b0 100644 --- a/GeminiIntents/IntentHandler.swift +++ b/GeminiIntents/IntentHandler.swift @@ -14,6 +14,8 @@ class IntentHandler: INExtension { // we also need to support extension-based handling because in-app handling isn't support