From ede43b351f71cb71b04d19231bf37a25413014da Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sat, 7 Aug 2021 23:08:58 +0200 Subject: [PATCH] Add in-app donations (Mac) --- Passepartout/App/macOS/CHANGELOG.md | 3 +- Passepartout/App/macOS/Menu/StatusMenu.swift | 33 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Passepartout/App/macOS/CHANGELOG.md b/Passepartout/App/macOS/CHANGELOG.md index 5b6ac911..17c26577 100644 --- a/Passepartout/App/macOS/CHANGELOG.md +++ b/Passepartout/App/macOS/CHANGELOG.md @@ -5,13 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.16.0 Beta 2697 (2021-07-31) +## Unreleased ### Added - Support for `--scramble xormask`. [#38](https://github.com/passepartoutvpn/passepartout-apple/issues/38) - Favorite provider locations. - Oeck provider. +- In-app donations. ## 1.15.3 (2021-07-20) diff --git a/Passepartout/App/macOS/Menu/StatusMenu.swift b/Passepartout/App/macOS/Menu/StatusMenu.swift index 4b418df8..dd3e2b37 100644 --- a/Passepartout/App/macOS/Menu/StatusMenu.swift +++ b/Passepartout/App/macOS/Menu/StatusMenu.swift @@ -24,6 +24,7 @@ // import Cocoa +import StoreKit import PassepartoutCore import TunnelKit import Convenience @@ -131,16 +132,23 @@ class StatusMenu: NSObject { let menuSupport = NSMenu() let itemCommunity = NSMenuItem(title: L10n.Organizer.Cells.JoinCommunity.caption.asContinuation, action: #selector(joinCommunity), keyEquivalent: "") -// let itemDonate = NSMenuItem(title: L10n.Organizer.Cells.Donate.caption.asContinuation, action: #selector(showDonations), keyEquivalent: "") + let itemDonate = NSMenuItem(title: L10n.Organizer.Cells.Donate.caption, action: nil, keyEquivalent: "") // let itemGitHubSponsors = NSMenuItem(title: L10n.Organizer.Cells.GithubSponsors.caption.asContinuation, action: #selector(seeGitHubSponsors), keyEquivalent: "") // let itemTranslate = NSMenuItem(title: L10n.Organizer.Cells.Translate.caption.asContinuation, action: #selector(offerToTranslate), keyEquivalent: "") + + let menuDonate = NSMenu() + ProductManager.shared.listProducts { [weak self] products, error in + self?.addDonations(fromProducts: products ?? [], to: menuDonate) + } + + menuSupport.setSubmenu(menuDonate, for: itemDonate) let itemFAQ = NSMenuItem(title: L10n.About.Cells.Faq.caption.asContinuation, action: #selector(visitFAQ), keyEquivalent: "") itemCommunity.target = self // itemDonate.target = self // itemGitHubSponsors.target = self // itemTranslate.target = self itemFAQ.target = self -// menuSupport.addItem(itemDonate) + menuSupport.addItem(itemDonate) menuSupport.addItem(itemCommunity) // menuSupport.addItem(.separator()) // menuSupport.addItem(itemGitHubSponsors) @@ -570,6 +578,27 @@ class StatusMenu: NSObject { // MARK: Helpers + private func addDonations(fromProducts products: [SKProduct], to menu: NSMenu) { + products.sorted { $0.price.decimalValue < $1.price.decimalValue }.forEach { + guard let p = Product(rawValue: $0.productIdentifier), p.isDonation, let price = $0.localizedPrice else { + return + } + let title = "\($0.localizedTitle) (\(price))" + let item = NSMenuItem(title: title, action: #selector(performDonation(_:)), keyEquivalent: "") + item.target = self + item.representedObject = $0 + menu.addItem(item) + } + } + + @objc private func performDonation(_ item: NSMenuItem) { + guard let product = item.representedObject as? SKProduct else { + return + } + ProductManager.shared.purchase(product) { _, _ in + } + } + private func reloadVpnStatus() { if vpn.isEnabled { itemToggleVPN.title = L10n.Service.Cells.Vpn.TurnOff.caption