diff --git a/README.md b/README.md index 4f39fde..e41c28f 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,7 @@ A special tag can be used as an alternative to refresh interval defined in plugi #### Other Parameters +* `#true` - refreshes plugin on click, before presenting the menu * `false` - doesn't wrap plugins in Bash when running * `streamable` - mark plugin as Streamable * `[var1:default value, var2:default value, ... ]` - this variables will be passed in plugin's environment, in later release SwiftBar will provide a UI to change values for these variables. diff --git a/SwiftBar/MenuBar/MenuBarItem.swift b/SwiftBar/MenuBar/MenuBarItem.swift index 372a80a..fda1aca 100644 --- a/SwiftBar/MenuBar/MenuBarItem.swift +++ b/SwiftBar/MenuBar/MenuBarItem.swift @@ -92,7 +92,7 @@ class MenubarItem: NSObject { contentUpdateCancellable = plugin?.contentUpdatePublisher .receive(on: menuUpdateQueue) .sink { [weak self] content in - guard self?.isOpen == false else { + guard self?.isOpen == false, plugin?.metadata?.refreshOnOpen == true else { self?.refreshOnClose = true return } @@ -605,9 +605,31 @@ extension MenubarItem { } func showMenu() { + if plugin?.metadata?.refreshOnOpen == true, plugin?.type == .Executable { + refreshAndShowMenu() + return + } barItem.menu = statusBarMenu barItem.button?.performClick(nil) } + + func refreshAndShowMenu() { + if #available(macOS 11.0, *) { + barItem.button?.image = NSImage(systemSymbolName: "hourglass", accessibilityDescription: nil) + barItem.button?.imagePosition = .imageLeft + } else { + barItem.button?.image = nil + barItem.button?.title = "..." + } + DispatchQueue.main.async { [weak self] in + self?.barItem.button?.image = nil + self?.barItem.button?.title.removeAll() + self?.plugin?.refresh() + self?.updateMenu(content: self?.plugin?.content) + self?.barItem.menu = self?.statusBarMenu + self?.barItem.button?.performClick(nil) + } + } @discardableResult func performItemAction(params: MenuLineParameters) -> Bool { if let href = params.href, let url = URL(string: href) { diff --git a/SwiftBar/Plugin/ExecutablePlugin.swift b/SwiftBar/Plugin/ExecutablePlugin.swift index 3e7eb28..4e3b2de 100644 --- a/SwiftBar/Plugin/ExecutablePlugin.swift +++ b/SwiftBar/Plugin/ExecutablePlugin.swift @@ -148,8 +148,7 @@ class ExecutablePlugin: Plugin { } @objc func scheduledContentUpdate() { - content = invoke() - enableTimer() + refresh() } } diff --git a/SwiftBar/Plugin/PluginMetadata.swift b/SwiftBar/Plugin/PluginMetadata.swift index 1175b5a..41aaaf5 100644 --- a/SwiftBar/Plugin/PluginMetadata.swift +++ b/SwiftBar/Plugin/PluginMetadata.swift @@ -27,12 +27,13 @@ enum PluginMetadataOption: String, CaseIterable { case hideSwiftBar case environment case runInBash + case refreshOnOpen var optionType: [PluginMetadataType] { switch self { case .title, .version, .author, .github, .desc, .about, .image, .dependencies: return [.bitbar, .xbar] - case .runInBash, .environment, .droptypes, .schedule, .type, .hideAbout, .hideRunInTerminal, .hideLastUpdated, .hideDisablePlugin, .hideSwiftBar: + case .runInBash, .environment, .droptypes, .schedule, .type, .hideAbout, .hideRunInTerminal, .hideLastUpdated, .hideDisablePlugin, .hideSwiftBar, .refreshOnOpen: return [.swiftbar] } } @@ -57,6 +58,7 @@ class PluginMetadata: ObservableObject { @Published var hideSwiftBar: Bool @Published var environment: [String: String] @Published var runInBash: Bool + @Published var refreshOnOpen: Bool var isEmpty: Bool { name.isEmpty @@ -74,7 +76,7 @@ class PluginMetadata: ObservableObject { return try? cron.next() } - init(name: String = "", version: String = "", author: String = "", github: String = "", desc: String = "", previewImageURL: URL? = nil, dependencies: [String] = [], aboutURL: URL? = nil, dropTypes: [String] = [], schedule: String = "", type: PluginType = .Executable, hideAbout: Bool = false, hideRunInTerminal: Bool = false, hideLastUpdated: Bool = false, hideDisablePlugin: Bool = false, hideSwiftBar: Bool = false, environment: [String: String] = [:], runInBash: Bool = true) { + init(name: String = "", version: String = "", author: String = "", github: String = "", desc: String = "", previewImageURL: URL? = nil, dependencies: [String] = [], aboutURL: URL? = nil, dropTypes: [String] = [], schedule: String = "", type: PluginType = .Executable, hideAbout: Bool = false, hideRunInTerminal: Bool = false, hideLastUpdated: Bool = false, hideDisablePlugin: Bool = false, hideSwiftBar: Bool = false, environment: [String: String] = [:], runInBash: Bool = true, refreshOnOpen: Bool = false) { self.name = name self.version = version self.author = author @@ -93,6 +95,7 @@ class PluginMetadata: ObservableObject { self.hideSwiftBar = hideSwiftBar self.environment = environment self.runInBash = runInBash + self.refreshOnOpen = refreshOnOpen } var shouldRunInBash: Bool { @@ -109,6 +112,9 @@ class PluginMetadata: ObservableObject { let closeTag = "" return script.slice(from: openTag, to: closeTag) } + if tag == .refreshOnOpen { + print(values) + } return values.last ?? "" } @@ -149,7 +155,9 @@ class PluginMetadata: ObservableObject { hideDisablePlugin: getTagValue(tag: .hideDisablePlugin) == "true", hideSwiftBar: getTagValue(tag: .hideSwiftBar) == "true", environment: environment, - runInBash: getTagValue(tag: .runInBash) == "false" ? false : true) + runInBash: getTagValue(tag: .runInBash) == "false" ? false : true, + refreshOnOpen: getTagValue(tag: .refreshOnOpen) == "true" ? true: false + ) } static func parser(fileURL: URL) -> PluginMetadata? { @@ -215,6 +223,8 @@ class PluginMetadata: ObservableObject { value = environment.map { "\($0.key):\($0.value)" }.joined(separator: ",") case .runInBash: value = runInBash ? "" : "false" + case .refreshOnOpen: + value = refreshOnOpen ? "true" : "" } guard !value.isEmpty else { return } let tag = option