diff --git a/Stats/Supporting Files/Assets.xcassets/support/Contents.json b/Stats/Supporting Files/Assets.xcassets/support/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Stats/Supporting Files/Assets.xcassets/support/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Stats/Supporting Files/Assets.xcassets/support/github.imageset/Contents.json b/Stats/Supporting Files/Assets.xcassets/support/github.imageset/Contents.json new file mode 100644 index 00000000..fb3bcd17 --- /dev/null +++ b/Stats/Supporting Files/Assets.xcassets/support/github.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "github.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Stats/Supporting Files/Assets.xcassets/support/github.imageset/github.png b/Stats/Supporting Files/Assets.xcassets/support/github.imageset/github.png new file mode 100644 index 00000000..e938c65f Binary files /dev/null and b/Stats/Supporting Files/Assets.xcassets/support/github.imageset/github.png differ diff --git a/Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/Contents.json b/Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/Contents.json new file mode 100644 index 00000000..78648d0a --- /dev/null +++ b/Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ko-fi.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/ko-fi.png b/Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/ko-fi.png new file mode 100644 index 00000000..63438a3e Binary files /dev/null and b/Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/ko-fi.png differ diff --git a/Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/Contents.json b/Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/Contents.json new file mode 100644 index 00000000..3efb5c56 --- /dev/null +++ b/Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "patreon.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/patreon.png b/Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/patreon.png new file mode 100644 index 00000000..32f3fb9d Binary files /dev/null and b/Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/patreon.png differ diff --git a/Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/Contents.json b/Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/Contents.json new file mode 100644 index 00000000..c659efb2 --- /dev/null +++ b/Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "paypal.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/paypal.png b/Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/paypal.png new file mode 100644 index 00000000..292efe55 Binary files /dev/null and b/Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/paypal.png differ diff --git a/Stats/Views/Settings.swift b/Stats/Views/Settings.swift index 0806cb7f..a2c88edf 100644 --- a/Stats/Views/Settings.swift +++ b/Stats/Views/Settings.swift @@ -118,6 +118,8 @@ private class SettingsView: NSView { private var dashboard: NSView = Dashboard() private var settings: NSView = ApplicationSettings() + private let supportPopover = NSPopover() + override init(frame: NSRect) { super.init(frame: CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.width, height: frame.height)) self.wantsLayer = true @@ -129,6 +131,9 @@ private class SettingsView: NSView { sidebar.blendingMode = .behindWindow sidebar.state = .active + self.supportPopover.behavior = .transient + self.supportPopover.contentViewController = self.supportView() + self.menuView.frame = NSRect( x: 0, y: self.navigationHeight, @@ -257,6 +262,40 @@ private class SettingsView: NSView { return button } + private func supportView() -> NSViewController { + let vc: NSViewController = NSViewController(nibName: nil, bundle: nil) + let view: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: 160, height: 40)) + view.spacing = 0 + view.orientation = .horizontal + + view.addArrangedSubview(supportButton(name: "GitHub Sponsors", image: "github", action: #selector(self.openGithub))) + view.addArrangedSubview(supportButton(name: "PayPal", image: "paypal", action: #selector(self.openPaypal))) + view.addArrangedSubview(supportButton(name: "Ko-fi", image: "ko-fi", action: #selector(self.openKofi))) + view.addArrangedSubview(supportButton(name: "Patreon", image: "patreon", action: #selector(self.openPatreon))) + + vc.view = view + return vc + } + + private func supportButton(name: String, image: String, action: Selector) -> NSButton { + let button = NSButtonWithPadding() + button.frame = CGRect(x: 0, y: 0, width: 24, height: 24) + button.verticalPadding = 16 + button.horizontalPadding = 16 + button.title = name + button.toolTip = name + button.bezelStyle = .regularSquare + button.translatesAutoresizingMaskIntoConstraints = false + button.imageScaling = .scaleNone + button.image = Bundle(for: type(of: self)).image(forResource: image)! + button.isBordered = false + button.target = self + button.focusRingType = .none + button.action = action + + return button + } + @objc private func openSettings(_ sender: Any) { NotificationCenter.default.post(name: .openModuleSettings, object: nil, userInfo: ["module": "settings"]) } @@ -265,10 +304,26 @@ private class SettingsView: NSView { NSWorkspace.shared.open(URL(string: "https://github.com/exelban/stats/issues/new")!) } - @objc private func donate(_ sender: Any) { + @objc private func donate(_ sender: NSButton) { + self.supportPopover.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY) + } + + @objc private func openGithub(_ sender: NSButton) { NSWorkspace.shared.open(URL(string: "https://github.com/sponsors/exelban")!) } + @objc private func openPaypal(_ sender: NSButton) { + NSWorkspace.shared.open(URL(string: "https://www.paypal.com/donate?hosted_button_id=3DS5JHDBATMTC")!) + } + + @objc private func openKofi(_ sender: NSButton) { + NSWorkspace.shared.open(URL(string: "https://ko-fi.com/exelban")!) + } + + @objc private func openPatreon(_ sender: NSButton) { + NSWorkspace.shared.open(URL(string: "https://patreon.com/exelban")!) + } + @objc private func closeApp(_ sender: Any) { NSApp.terminate(sender) }