Improve URL Scheme consistency #280

This commit is contained in:
Alex Mazanov 2022-02-12 07:01:46 -08:00
parent f25db9dfee
commit 56bf483170
No known key found for this signature in database
GPG Key ID: FD35C3C7C1D34AB4
3 changed files with 31 additions and 38 deletions

View File

@ -265,13 +265,15 @@ You can mark a plugin as streamable with a special metadata property `<swiftbar.
| Endpoint | Parameter | Description | Example |
| ------------- | ------------- |------------- | ------------- |
| refreshallplugins | none | Force refresh all loaded plugins | `swiftbar://refreshallplugins` |
| refreshplugin | `name` plugin [name](#plugin-naming) | Force refresh plugin by name | `swiftbar://refreshplugin?name=myplugin` |
| refreshplugin | `name` or `plugin` plugin [name](#plugin-naming) | Force refresh plugin by name | `swiftbar://refreshplugin?name=myplugin` |
| refreshplugin | `index` plugin index in menubar, starting from `0` | Force refresh plugin by its position in menubar | `swiftbar://refreshplugin?index=1` |
| enableplugin | `name` plugin [name](#plugin-naming) | Enable plugin by name | `swiftbar://enableplugin?name=myplugin` |
| disableplugin | `name` plugin [name](#plugin-naming) | Disable plugin by name | `swiftbar://disableplugin?name=myplugin` |
| toggleplugin | `name` plugin [name](#plugin-naming) | Toggle(enable\disable) plugin by name | `swiftbar://toggleplugin?name=myplugin` |
| enableplugin | `name` or `plugin` plugin [name](#plugin-naming) | Enable plugin by name | `swiftbar://enableplugin?name=myplugin` |
| disableplugin | `name` or `plugin` plugin [name](#plugin-naming) | Disable plugin by name | `swiftbar://disableplugin?name=myplugin` |
| toggleplugin | `name` or `plugin` plugin [name](#plugin-naming) | Toggle(enable\disable) plugin by name | `swiftbar://toggleplugin?name=myplugin` |
| addplugin | `src` source URL to plugin file | Add plugin to Swiftbar from URL | `swiftbar://addplugin?src=https://coolplugin` |
| notify | `plugin` plugin [name](#plugin-naming). Notification fields: `title`, `subtitle`, `body`. `href` to open an URL on click (including custom URL schemes). `silent=true` to disable sound | Show notification | `swiftbar://notify?plugin=MyPlugin&title=title&subtitle=subtitle&body=body&silent=true` |
| notify | `name` or `plugin` plugin [name](#plugin-naming). Notification fields: `title`, `subtitle`, `body`. `href` to open an URL on click (including custom URL schemes). `silent=true` to disable sound | Show notification | `swiftbar://notify?plugin=MyPlugin&title=title&subtitle=subtitle&body=body&silent=true` |
LTP: instead of plugin [name](#plugin-naming) you can(and probably should) use plugin file name, this considered a unique plugin ID where name can be the same between multiple plugins. If your plugin's filepath is `~/Documents/SwiftBar/myplugin.1m.sh` then name is `myplugin` and ID `myplugin.1m.sh`
## Preferences aka 'defaults'

View File

@ -103,14 +103,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, SPUStandardUserDriverDelegat
pluginManager.terminateAllPlugins()
}
func getPluginFromURL(url: URL) -> Plugin? {
guard let identifier = url.queryParameters?["plugin"] ?? url.queryParameters?["name"] else { return nil }
return pluginManager.getPluginByNameOrID(identifier: identifier)
}
func application(_: NSApplication, open urls: [URL]) {
for url in urls {
switch url.host?.lowercased() {
case "refreshallplugins":
pluginManager.refreshAllPlugins()
case "refreshplugin":
if let name = url.queryParameters?["name"] {
pluginManager.refreshPlugin(named: name)
if let plugin = getPluginFromURL(url: url) {
plugin.refresh()
return
}
if let indexStr = url.queryParameters?["index"], let index = Int(indexStr) {
@ -118,25 +123,25 @@ class AppDelegate: NSObject, NSApplicationDelegate, SPUStandardUserDriverDelegat
return
}
case "disableplugin":
if let name = url.queryParameters?["name"] {
pluginManager.disablePlugin(named: name)
if let plugin = getPluginFromURL(url: url) {
pluginManager.disablePlugin(plugin: plugin)
}
case "enableplugin":
if let name = url.queryParameters?["name"] {
pluginManager.enablePlugin(named: name)
if let plugin = getPluginFromURL(url: url) {
pluginManager.enablePlugin(plugin: plugin)
}
case "toggleplugin":
if let name = url.queryParameters?["name"] {
pluginManager.togglePlugin(named: name)
if let plugin = getPluginFromURL(url: url) {
pluginManager.togglePlugin(plugin: plugin)
}
case "addplugin":
if let src = url.queryParameters?["src"], let url = URL(string: src) {
pluginManager.importPlugin(from: url)
}
case "notify":
guard let pluginID = url.queryParameters?["plugin"] else { return }
guard let plugin = getPluginFromURL(url: url) else { return }
let paramsString = url.queryParameters?.map { "\($0.key)=\($0.value.escaped())" }.joined(separator: " ") ?? ""
pluginManager.showNotification(pluginID: pluginID,
pluginManager.showNotification(plugin: plugin,
title: url.queryParameters?["title"],
subtitle: url.queryParameters?["subtitle"],
body: url.queryParameters?["body"],

View File

@ -75,28 +75,22 @@ class PluginManager: ObservableObject {
enabledPlugins.isEmpty && !prefs.stealthMode ? barItem.show() : barItem.hide()
}
func getPluginByNameOrID(identifier: String) -> Plugin? {
plugins.first(where: { $0.id.lowercased() == identifier.lowercased() }) ??
plugins.first(where: { $0.name.lowercased() == identifier.lowercased() })
}
func disablePlugin(plugin: Plugin) {
os_log("Disabling plugin \n%{public}@", log: Log.plugin, plugin.description)
plugin.disable()
}
func disablePlugin(named name: String) {
guard let plugin = plugins.first(where: { $0.name.lowercased() == name.lowercased() }) else { return }
disablePlugin(plugin: plugin)
}
func enablePlugin(plugin: Plugin) {
os_log("Enabling plugin \n%{public}@", log: Log.plugin, plugin.description)
plugin.enable()
}
func enablePlugin(named name: String) {
guard let plugin = plugins.first(where: { $0.name.lowercased() == name.lowercased() }) else { return }
enablePlugin(plugin: plugin)
}
func togglePlugin(named name: String) {
guard let plugin = plugins.first(where: { $0.name.lowercased() == name.lowercased() }) else { return }
func togglePlugin(plugin: Plugin) {
plugin.enabled ? disablePlugin(plugin: plugin) : enablePlugin(plugin: plugin)
}
@ -209,11 +203,6 @@ class PluginManager: ObservableObject {
menuBarItems.values.forEach { $0.updateMenu(content: $0.plugin?.content) }
}
func refreshPlugin(named name: String) {
guard let plugin = plugins.first(where: { $0.name.lowercased() == name.lowercased() }) else { return }
plugin.refresh()
}
func refreshPlugin(with index: Int) {
guard plugins.indices.contains(index) else { return }
plugins[index].refresh()
@ -262,18 +251,15 @@ class PluginManager: ObservableObject {
}
extension PluginManager {
func showNotification(pluginID: PluginID, title: String?, subtitle: String?, body: String?, href: String?, commandParams: String?, silent: Bool = false) {
guard let plugin = plugins.first(where: { $0.id == pluginID }),
plugin.enabled else { return }
func showNotification(plugin: Plugin, title: String?, subtitle: String?, body: String?, href: String?, commandParams: String?, silent: Bool = false) {
let content = UNMutableNotificationContent()
content.title = title ?? ""
content.subtitle = subtitle ?? ""
content.body = body ?? ""
content.sound = silent ? nil : .default
content.threadIdentifier = pluginID
content.threadIdentifier = plugin.id
content.userInfo[SystemNotificationName.pluginID] = pluginID
content.userInfo[SystemNotificationName.pluginID] = plugin.id
if let urlString = href,
let url = URL(string: urlString), url.host != nil, url.scheme != nil