Skip to content

Commit

Permalink
main: auto-launch from URL scheme
Browse files Browse the repository at this point in the history
Resolves #3
  • Loading branch information
osy committed Aug 12, 2021
1 parent 41e171b commit 69f50f3
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 2 deletions.
41 changes: 39 additions & 2 deletions Jitterbug/DeviceDetailsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct DeviceDetailsView: View {
launchApplication(app)
} label: {
AppItemView(app: app, saved: true, hostIdentifier: host.identifier)
}
}.appContextMenu(host: host, app: app)
}
}
}
Expand All @@ -85,7 +85,7 @@ struct DeviceDetailsView: View {
launchApplication(app)
} label: {
AppItemView(app: app, saved: false, hostIdentifier: host.identifier)
}
}.appContextMenu(host: host, app: app)
}
}
}
Expand Down Expand Up @@ -157,6 +157,14 @@ struct DeviceDetailsView: View {
}
}
}
}.onChange(of: main.selectedLaunchAppId) { appId in
guard apps.count > 0 else {
return
}
guard let autoLaunchApp = try? main.processAutoLaunch(withApps: apps) else {
return
}
launchApplication(autoLaunchApp)
}
}

Expand Down Expand Up @@ -195,11 +203,17 @@ struct DeviceDetailsView: View {
}

private func refreshAppsList(onSuccess: @escaping () -> Void) {
var autoLaunchApp: JBApp?
main.backgroundTask(message: NSLocalizedString("Querying installed apps...", comment: "DeviceDetailsView")) {
try host.updateInfo()
apps = try host.installedApps()
main.archiveSavedHosts()
autoLaunchApp = try main.processAutoLaunch(withApps: apps)
onSuccess()
} onComplete: {
if let app = autoLaunchApp {
launchApplication(app)
}
}
}

Expand Down Expand Up @@ -251,6 +265,29 @@ struct DeviceDetailsView: View {
}
}

struct AppContextMenuViewModifier: ViewModifier {
@EnvironmentObject private var main: Main
let host: JBHostDevice
let app: JBApp

func body(content: Content) -> some View {
content.contextMenu {
Button {
UIPasteboard.general.url = main.encodeURL(forHost: host, launchingApp: app)
} label: {
Label("Copy Shortcut URL", systemImage: "link")
.labelStyle(DefaultLabelStyle())
}
}
}
}

extension View {
func appContextMenu(host: JBHostDevice, app: JBApp) -> some View {
self.modifier(AppContextMenuViewModifier(host: host, app: app))
}
}

struct DeviceDetailsView_Previews: PreviewProvider {
static var previews: some View {
DeviceDetailsView(host: JBHostDevice(hostname: "", address: Data()))
Expand Down
8 changes: 8 additions & 0 deletions Jitterbug/DeviceListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ struct ContextMenuViewModifier: ViewModifier {

func body(content: Content) -> some View {
content.contextMenu {
#if os(iOS)
Button {
UIPasteboard.general.url = main.encodeURL(forHost: host)
} label: {
Label("Copy Shortcut URL", systemImage: "link")
.labelStyle(DefaultLabelStyle())
}
#endif
Button {
main.savePairing(nil, forHostIdentifier: host.identifier)
main.saveDiskImage(nil, signature: nil, forHostIdentifier: host.identifier)
Expand Down
12 changes: 12 additions & 0 deletions Jitterbug/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.osy86.Jitterbug</string>
<key>CFBundleURLSchemes</key>
<array>
<string>jitterbug</string>
</array>
</dict>
<dict/>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
Expand Down
3 changes: 3 additions & 0 deletions Jitterbug/JitterbugApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ struct JitterbugApp: App {
WindowGroup {
ContentView()
.environmentObject(main)
.onOpenURL { url in
main.loadURL(url)
}
}
.onChange(of: scenePhase) { newScenePhase in
if newScenePhase == .active {
Expand Down
53 changes: 53 additions & 0 deletions Jitterbug/Main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Main: NSObject, ObservableObject {
@Published var savedHosts: [JBHostDevice] = []
@Published var foundHosts: [JBHostDevice] = []
@Published var selectedHostId: String?
@Published var selectedLaunchAppId: String?

@Published var pairings: [URL] = []
@Published var supportImages: [URL] = []
Expand Down Expand Up @@ -542,3 +543,55 @@ extension Main {
manager.connection.stopVPNTunnel()
}
}

// MARK: - URL parsing
extension Main {
func encodeURL(forHost host: JBHostDevice, launchingApp app: JBApp? = nil) -> URL {
var components = URLComponents()
components.scheme = "jitterbug"
components.host = host.identifier
if let app = app {
components.queryItems = [
URLQueryItem(name: "launch", value: app.bundleIdentifier)
]
}
return components.url!
}

func loadURL(_ url: URL) {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
guard components.scheme == "jitterbug" else {
if components.scheme != "file" {
print("[URL] unknown scheme \(String(describing: components.scheme))")
}
return
}
selectedHostId = components.host
guard let queryItems = components.queryItems else {
print("[URL] no query to handle")
return
}
for item in queryItems {
if item.name == "launch" {
selectedLaunchAppId = item.value
}
}
}

func processAutoLaunch(withApps apps: [JBApp]) throws -> JBApp? {
guard let launchId = selectedLaunchAppId else {
return nil
}
DispatchQueue.main.async {
self.selectedLaunchAppId = nil
}
let selectedApp = apps.first { app in
app.bundleIdentifier == launchId
}
if let selectedApp = selectedApp {
return selectedApp
} else {
throw NSLocalizedString("Cannot find \(launchId)", comment: "Main")
}
}
}

0 comments on commit 69f50f3

Please sign in to comment.