From a5232bcebf5138d205aa81a4c908b5b34741e211 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Wed, 1 Sep 2021 23:01:54 +0200 Subject: [PATCH] feat: added a popover to the Support button which allows selecting a support provider (GH Sponsors, PayPal, Ko-fi, Patreon) --- .../Assets.xcassets/support/Contents.json | 6 ++ .../support/github.imageset/Contents.json | 21 +++++++ .../support/github.imageset/github.png | Bin 0 -> 800 bytes .../support/ko-fi.imageset/Contents.json | 21 +++++++ .../support/ko-fi.imageset/ko-fi.png | Bin 0 -> 1093 bytes .../support/patreon.imageset/Contents.json | 21 +++++++ .../support/patreon.imageset/patreon.png | Bin 0 -> 563 bytes .../support/paypal.imageset/Contents.json | 21 +++++++ .../support/paypal.imageset/paypal.png | Bin 0 -> 1004 bytes Stats/Views/Settings.swift | 57 +++++++++++++++++- 10 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 Stats/Supporting Files/Assets.xcassets/support/Contents.json create mode 100644 Stats/Supporting Files/Assets.xcassets/support/github.imageset/Contents.json create mode 100644 Stats/Supporting Files/Assets.xcassets/support/github.imageset/github.png create mode 100644 Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/Contents.json create mode 100644 Stats/Supporting Files/Assets.xcassets/support/ko-fi.imageset/ko-fi.png create mode 100644 Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/Contents.json create mode 100644 Stats/Supporting Files/Assets.xcassets/support/patreon.imageset/patreon.png create mode 100644 Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/Contents.json create mode 100644 Stats/Supporting Files/Assets.xcassets/support/paypal.imageset/paypal.png 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 0000000000000000000000000000000000000000..e938c65f2aee972b5f8c0c248dd1c23fb4b8ef09 GIT binary patch literal 800 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^> z;_2(k{**&rfYnNrYmppKp4rpIF~s6@?POo?kVJ{L^*<*#q)C)a5NOF++{`U*s3us) z_OHQ#qa|z?hxjl4n2z1sJ~R7dJU%5K(AYG~rK2fq2G6#DDI5PR;E`T0wr}3C_3t)U zzCT<$|9Rc~=az;{EGr%|`oCB*Qzzh&@#Z}bmG3JaQ|<8FJ-6ie>KlcZ@+QX#C7%*B zxB09#XXnEXO+%w4vfnTKe|VwrvRk5?ZP0h!sw&^Atc$f@PXtbGy773~D%RUFB^Pb4 z&n-Sz`aP!Pf*JR!yj#ity&y+#!5DXyKvT_->F`A+JsI& zydtt(ZHnzavwsZ|2MRl)h4~+QPiVWX#F#1cTt$vGbIGr39#>7`TDmuj^~G+v7vkIy zwu>qD@Wza%X=f^rDkYtpnZbK}!(rY3KdzPkE4e2qADQlRWJY=In-!m@H7B0t^N9>d zuYHw$-lp)d_{78;`u|o%9BI-#vPb)s_U$>}R(sn``B3s}vD3b!dlQNd#D1^MyH+;a zw_@V|ebp0dt~VAqZ#cp ztHiA#-FM9npaw~h4Z-!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?e421sKjn}Y5aiCPDlKGSU^ek|aSZV|zV(`SPH3nE z>x2CH)m1N@8sZE5boqSD5kVvi^u)xMe^y^JHAi*7S-FkX_EcTbo*{ZqaEG ztzt6a`A4O)$9mj{UH3Hq)wt&B#Qbyijn-?dldcCIklPb4&bhhhpVqg3?4NEbt$*z7 zkv&&>gZ8Cau8VdgTvPB6Xu1|9=C{Cp?b5XLC98FL&C1QPy(hPNy0~?TrXTleTNke4 zI6Z6Po=Hi@+tMc9Q>}deRku9)@*x%`uSgSvz)u&?Kjw>_BeZz!jX4R{RtmmNCY;9I z|9q!x&L~)vvSr50*h$-eFHGIGCTF6n?2UOzr}x~}nr>M*=OE*|*x=sDe|vf_ZSQ<1 zSMapzXtsOX!P~EI+wR(Qw9j<=@5GE-ycdL; z%E!95rmu8y>z?TyoEp#LQ+u_Z`OT}{H*3}|k7fPkyVHHWGt4{_!JKe|` zyi~(r-Xj^aYo{vpewj^FsrjZEzJ61guKwOLt3r)~XB8hj_Ov@?;=#^Iwdu!dt5+@v z>vvAe(thzEq6E9J%;AM91$B#_oVc(hNGx>G zY(7H+zTltQm-A=#F6H;D zeKO5%Ca===XBYDY9@hWL{VB}r9o!PVF*OpHrBq8?BT7;dOH!?pi&B9UgOP!ep{{|2 zuCZZ=p_!GTxs@T1YhqNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlQCtXw8Pn%q0@=r2;_2(k{**&rKuEddQJ)6`1EZR!i(`nz>8)3MwOaxu+CRRQ zTs&cV&XnmYnU^%IH@d9(!S>CrrFHIJeaEmA$IS^#k6iNJBw;4Pt(tFW5-WBlY2NcQ z!NGr~Kc5pn_xGK0_E$bB%Eez8{Bu4_F)F0INNcfEdbi_2TTzJMw#o&sw$?H!ecSzL zsr;&Gd&;iPkzi8ltIn}`e(v8SmJ`)U8sUB&DM_ZL8;@jcxaBx4Q=ReHjP*Yqf_>Bu zn#h_u3LASG%(>MfbN1?j#%m!LoVH0#sq|qzUvq4I$tkSQK6b-rgDVb@NxHWufozM@| Oz~JfX=d#Wzp$P!%w9-}p literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..292efe55d837f966d2e6ed3401020ad0017d2629 GIT binary patch literal 1004 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZKG?e4|-zS^mS!_${{ZxW>y=#emMgJ(``=|#}JR>bEkS|2M3C@ z?yt?CwahcR^GeoQv&_(tH5VKYc9tq>Xt2s!Xml_yyw(^j|ASein@_|&tliGdO7zIT zhNh-#Ty`7y7e*~~d|~bTu4uxNojYq)-#xVbzUKX$(rb3dIj%j7Zs2h;O;Eh1dWv@d_%oVO1Qy0WGsMcYmvmi$P3yr>7Fw~#Tea$ zI)47~EnM-|`s1$Zid*h_Y@W5(cQXXxc{Pnyf zG2vOzq_eATWbFKMWqpVD<}0rM6}GZI>#p_%-D_OfhMj6K=wg1m6_9lf*t4Lr!Xw>qI_Z~y(6RSdz`HTmKgv5 literal 0 HcmV?d00001 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) }