Tell old purchasers how to redeem full version

This commit is contained in:
Davide De Rosa 2021-02-11 23:40:16 +01:00
parent 551e57dcd7
commit bd2290d1fc
6 changed files with 73 additions and 15 deletions

View File

@ -746,7 +746,7 @@ internal enum L10n {
internal static let title = L10n.tr("Core", "purchase.title") internal static let title = L10n.tr("Core", "purchase.title")
internal enum Cells { internal enum Cells {
internal enum FullVersion { internal enum FullVersion {
/// - All providers (including future ones)\n%@ /// All providers (including future ones)\n%@
internal static func extraDescription(_ p1: Any) -> String { internal static func extraDescription(_ p1: Any) -> String {
return L10n.tr("Core", "purchase.cells.full_version.extra_description", String(describing: p1)) return L10n.tr("Core", "purchase.cells.full_version.extra_description", String(describing: p1))
} }

View File

@ -11,17 +11,17 @@
<objects> <objects>
<viewController id="Rv5-Zx-TH3" customClass="PurchaseViewController" customModule="Passepartout" customModuleProvider="target" sceneMemberID="viewController"> <viewController id="Rv5-Zx-TH3" customClass="PurchaseViewController" customModule="Passepartout" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="8QZ-37-H7U"> <view key="view" id="8QZ-37-H7U">
<rect key="frame" x="0.0" y="0.0" width="442" height="500"/> <rect key="frame" x="0.0" y="0.0" width="442" height="480"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<scrollView autohidesScrollers="YES" horizontalLineScroll="80" horizontalPageScroll="10" verticalLineScroll="80" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WTb-Wq-BLo"> <scrollView autohidesScrollers="YES" horizontalLineScroll="80" horizontalPageScroll="10" verticalLineScroll="80" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WTb-Wq-BLo">
<rect key="frame" x="20" y="120" width="402" height="360"/> <rect key="frame" x="20" y="156" width="402" height="304"/>
<clipView key="contentView" id="dfi-7t-ces"> <clipView key="contentView" id="dfi-7t-ces">
<rect key="frame" x="1" y="1" width="400" height="358"/> <rect key="frame" x="1" y="1" width="400" height="302"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="80" rowSizeStyle="automatic" viewBased="YES" id="9w7-b6-jXh"> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowHeight="80" rowSizeStyle="automatic" viewBased="YES" id="9w7-b6-jXh">
<rect key="frame" x="0.0" y="0.0" width="400" height="358"/> <rect key="frame" x="0.0" y="0.0" width="400" height="302"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="17" height="0.0"/> <size key="intercellSpacing" width="17" height="0.0"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -96,7 +96,7 @@
</subviews> </subviews>
</clipView> </clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="CeE-dS-NyP"> <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="CeE-dS-NyP">
<rect key="frame" x="1" y="329" width="400" height="16"/> <rect key="frame" x="1" y="343" width="400" height="16"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="2Ip-OW-X0v"> <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="2Ip-OW-X0v">
@ -105,7 +105,7 @@
</scroller> </scroller>
</scrollView> </scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TKV-I9-3N8"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TKV-I9-3N8">
<rect key="frame" x="19" y="96" width="404" height="16"/> <rect key="frame" x="19" y="132" width="404" height="16"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="400" id="uyO-So-B3k"/> <constraint firstAttribute="width" constant="400" id="uyO-So-B3k"/>
</constraints> </constraints>
@ -116,10 +116,10 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
<progressIndicator hidden="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="2hB-Jy-QEw"> <progressIndicator hidden="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="2hB-Jy-QEw">
<rect key="frame" x="213" y="22" width="16" height="16"/> <rect key="frame" x="213" y="58" width="16" height="16"/>
</progressIndicator> </progressIndicator>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XMI-x0-24k"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XMI-x0-24k">
<rect key="frame" x="230" y="13" width="94" height="32"/> <rect key="frame" x="230" y="49" width="94" height="32"/>
<buttonCell key="cell" type="push" title="&lt;restore&gt;" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Tce-5t-Hj1"> <buttonCell key="cell" type="push" title="&lt;restore&gt;" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Tce-5t-Hj1">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -129,7 +129,7 @@
</connections> </connections>
</button> </button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lBO-a6-qnj"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lBO-a6-qnj">
<rect key="frame" x="322" y="13" width="107" height="32"/> <rect key="frame" x="322" y="49" width="107" height="32"/>
<buttonCell key="cell" type="push" title="&lt;purchase&gt;" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uxN-5f-y4i"> <buttonCell key="cell" type="push" title="&lt;purchase&gt;" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uxN-5f-y4i">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -139,7 +139,7 @@
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="72F-hB-DPP"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="72F-hB-DPP">
<rect key="frame" x="19" y="60" width="404" height="16"/> <rect key="frame" x="19" y="96" width="404" height="16"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="400" id="ejH-6r-pkl"/> <constraint firstAttribute="width" constant="400" id="ejH-6r-pkl"/>
</constraints> </constraints>
@ -149,13 +149,25 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oiz-24-DEQ">
<rect key="frame" x="19" y="20" width="404" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="400" id="rN6-hj-XWV"/>
</constraints>
<textFieldCell key="cell" title="&lt;legacy&gt;" id="rKm-Ve-QuT">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstAttribute="bottom" secondItem="oiz-24-DEQ" secondAttribute="bottom" constant="20" symbolic="YES" id="2i0-3K-crG"/>
<constraint firstItem="72F-hB-DPP" firstAttribute="top" secondItem="TKV-I9-3N8" secondAttribute="bottom" constant="20" id="8kK-yQ-UGc"/> <constraint firstItem="72F-hB-DPP" firstAttribute="top" secondItem="TKV-I9-3N8" secondAttribute="bottom" constant="20" id="8kK-yQ-UGc"/>
<constraint firstAttribute="bottom" secondItem="lBO-a6-qnj" secondAttribute="bottom" constant="20" symbolic="YES" id="ENp-WT-Z1C"/>
<constraint firstAttribute="trailing" secondItem="WTb-Wq-BLo" secondAttribute="trailing" constant="20" symbolic="YES" id="Ed7-QK-8qI"/> <constraint firstAttribute="trailing" secondItem="WTb-Wq-BLo" secondAttribute="trailing" constant="20" symbolic="YES" id="Ed7-QK-8qI"/>
<constraint firstItem="lBO-a6-qnj" firstAttribute="leading" secondItem="XMI-x0-24k" secondAttribute="trailing" constant="12" symbolic="YES" id="HGl-z7-xCS"/> <constraint firstItem="lBO-a6-qnj" firstAttribute="leading" secondItem="XMI-x0-24k" secondAttribute="trailing" constant="12" symbolic="YES" id="HGl-z7-xCS"/>
<constraint firstItem="XMI-x0-24k" firstAttribute="centerY" secondItem="lBO-a6-qnj" secondAttribute="centerY" id="Lkd-1j-rt9"/> <constraint firstItem="XMI-x0-24k" firstAttribute="centerY" secondItem="lBO-a6-qnj" secondAttribute="centerY" id="Lkd-1j-rt9"/>
<constraint firstItem="oiz-24-DEQ" firstAttribute="top" secondItem="lBO-a6-qnj" secondAttribute="bottom" constant="20" id="O9i-SG-bNc"/>
<constraint firstItem="lBO-a6-qnj" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="9w7-b6-jXh" secondAttribute="leading" id="PAx-YO-dub"/> <constraint firstItem="lBO-a6-qnj" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="9w7-b6-jXh" secondAttribute="leading" id="PAx-YO-dub"/>
<constraint firstItem="TKV-I9-3N8" firstAttribute="trailing" secondItem="9w7-b6-jXh" secondAttribute="trailing" id="QMH-Dc-Vbo"/> <constraint firstItem="TKV-I9-3N8" firstAttribute="trailing" secondItem="9w7-b6-jXh" secondAttribute="trailing" id="QMH-Dc-Vbo"/>
<constraint firstItem="XMI-x0-24k" firstAttribute="leading" secondItem="2hB-Jy-QEw" secondAttribute="trailing" constant="8" symbolic="YES" id="Rlz-6Y-GTq"/> <constraint firstItem="XMI-x0-24k" firstAttribute="leading" secondItem="2hB-Jy-QEw" secondAttribute="trailing" constant="8" symbolic="YES" id="Rlz-6Y-GTq"/>
@ -168,6 +180,8 @@
<constraint firstItem="2hB-Jy-QEw" firstAttribute="centerY" secondItem="lBO-a6-qnj" secondAttribute="centerY" id="mX6-db-4Tp"/> <constraint firstItem="2hB-Jy-QEw" firstAttribute="centerY" secondItem="lBO-a6-qnj" secondAttribute="centerY" id="mX6-db-4Tp"/>
<constraint firstItem="TKV-I9-3N8" firstAttribute="leading" secondItem="9w7-b6-jXh" secondAttribute="leading" id="pNd-TR-JzE"/> <constraint firstItem="TKV-I9-3N8" firstAttribute="leading" secondItem="9w7-b6-jXh" secondAttribute="leading" id="pNd-TR-JzE"/>
<constraint firstItem="WTb-Wq-BLo" firstAttribute="top" secondItem="8QZ-37-H7U" secondAttribute="top" constant="20" symbolic="YES" id="q88-zV-efL"/> <constraint firstItem="WTb-Wq-BLo" firstAttribute="top" secondItem="8QZ-37-H7U" secondAttribute="top" constant="20" symbolic="YES" id="q88-zV-efL"/>
<constraint firstItem="oiz-24-DEQ" firstAttribute="trailing" secondItem="72F-hB-DPP" secondAttribute="trailing" id="rdm-Wx-VIj"/>
<constraint firstItem="oiz-24-DEQ" firstAttribute="leading" secondItem="72F-hB-DPP" secondAttribute="leading" id="wkn-4L-Olz"/>
</constraints> </constraints>
</view> </view>
<connections> <connections>
@ -175,13 +189,23 @@
<outlet property="buttonPurchase" destination="lBO-a6-qnj" id="m5t-5u-goQ"/> <outlet property="buttonPurchase" destination="lBO-a6-qnj" id="m5t-5u-goQ"/>
<outlet property="buttonRestore" destination="XMI-x0-24k" id="Xhd-Ph-uUY"/> <outlet property="buttonRestore" destination="XMI-x0-24k" id="Xhd-Ph-uUY"/>
<outlet property="labelFooter" destination="TKV-I9-3N8" id="DTN-XY-TSD"/> <outlet property="labelFooter" destination="TKV-I9-3N8" id="DTN-XY-TSD"/>
<outlet property="labelLegacy" destination="oiz-24-DEQ" id="YWQ-uG-YvG"/>
<outlet property="labelRestore" destination="72F-hB-DPP" id="rnt-Zy-gEz"/> <outlet property="labelRestore" destination="72F-hB-DPP" id="rnt-Zy-gEz"/>
<outlet property="tableView" destination="9w7-b6-jXh" id="0Ju-MH-sbN"/> <outlet property="tableView" destination="9w7-b6-jXh" id="0Ju-MH-sbN"/>
</connections> </connections>
</viewController> </viewController>
<customObject id="GVf-vI-DWL" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> <customObject id="GVf-vI-DWL" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<textView verticallyResizable="YES" usesFontPanel="YES" usesInspectorBar="YES" findStyle="bar" allowsDocumentBackgroundColorChange="YES" usesRuler="YES" smartInsertDelete="YES" id="hbw-dF-UJU">
<rect key="frame" x="0.0" y="0.0" width="240" height="135"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<size key="minSize" width="240" height="135"/>
<size key="maxSize" width="240" height="10000000"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
</textView>
</objects> </objects>
<point key="canvasLocation" x="428" y="-9"/> <point key="canvasLocation" x="428" y="6.5"/>
</scene> </scene>
</scenes> </scenes>
</document> </document>

View File

@ -159,6 +159,16 @@ internal enum L10n {
} }
} }
} }
internal enum Purchase {
internal enum Sections {
internal enum Products {
internal enum Footer {
/// If you bought the old macOS app (1.14.0), skip this step. Instead, send your Apple invoice to this address to restore full version:
internal static let macLegacy = L10n.tr("App", "purchase.sections.products.footer.mac_legacy")
}
}
}
}
internal enum Service { internal enum Service {
internal enum Cells { internal enum Cells {
internal enum Addresses { internal enum Addresses {
@ -768,7 +778,7 @@ internal enum L10n {
internal static let title = L10n.tr("Core", "purchase.title") internal static let title = L10n.tr("Core", "purchase.title")
internal enum Cells { internal enum Cells {
internal enum FullVersion { internal enum FullVersion {
/// - All providers (including future ones)\n%@ /// All providers (including future ones)\n%@
internal static func extraDescription(_ p1: Any) -> String { internal static func extraDescription(_ p1: Any) -> String {
return L10n.tr("Core", "purchase.cells.full_version.extra_description", String(describing: p1)) return L10n.tr("Core", "purchase.cells.full_version.extra_description", String(describing: p1))
} }

View File

@ -40,6 +40,10 @@ class PurchaseViewController: NSViewController {
static let product = NSUserInterfaceItemIdentifier("ProductCellIdentifier") static let product = NSUserInterfaceItemIdentifier("ProductCellIdentifier")
} }
private let legacyEmail = "issues+maclegacy@passepartoutvpn.app"
private lazy var legacyEmailURL = URL(string: "mailto:\(legacyEmail)")!
@IBOutlet private weak var tableView: NSTableView! @IBOutlet private weak var tableView: NSTableView!
@IBOutlet private weak var labelFooter: NSTextField! @IBOutlet private weak var labelFooter: NSTextField!
@ -52,6 +56,8 @@ class PurchaseViewController: NSViewController {
@IBOutlet private weak var buttonRestore: NSButton! @IBOutlet private weak var buttonRestore: NSButton!
@IBOutlet private weak var labelLegacy: NSTextField!
var feature: Product? var feature: Product?
weak var delegate: PurchaseViewControllerDelegate? weak var delegate: PurchaseViewControllerDelegate?
@ -106,6 +112,16 @@ class PurchaseViewController: NSViewController {
buttonPurchase.title = L10n.Core.Purchase.title buttonPurchase.title = L10n.Core.Purchase.title
buttonRestore.title = L10n.Core.Purchase.Cells.Restore.title buttonRestore.title = L10n.Core.Purchase.Cells.Restore.title
let legacyEmailLink = NSAttributedString(
string: legacyEmail,
attributes: [.link: legacyEmailURL]
)
let legacyText = NSMutableAttributedString()
legacyText.append(NSAttributedString(string: L10n.App.Purchase.Sections.Products.Footer.macLegacy))
legacyText.append(legacyEmailLink)
labelLegacy.attributedStringValue = legacyText
labelLegacy.addGestureRecognizer(NSClickGestureRecognizer(target: self, action: #selector(sendLegacyEmail)))
tableView.usesAutomaticRowHeights = true tableView.usesAutomaticRowHeights = true
tableView.reloadData() tableView.reloadData()
} }
@ -156,6 +172,10 @@ class PurchaseViewController: NSViewController {
} }
} }
@objc private func sendLegacyEmail() {
NSWorkspace.shared.open(legacyEmailURL)
}
private func purchaseFeature() { private func purchaseFeature() {
guard let sk = skFeature else { guard let sk = skFeature else {
return return

View File

@ -71,3 +71,5 @@
"menu.support.title" = "Support"; "menu.support.title" = "Support";
"menu.quit.title" = "Quit %@"; "menu.quit.title" = "Quit %@";
"menu.quit.messages.confirm" = "The VPN, if enabled, will still run in the background. Do you want to quit?"; "menu.quit.messages.confirm" = "The VPN, if enabled, will still run in the background. Do you want to quit?";
"purchase.sections.products.footer.mac_legacy" = "If you bought the old macOS app (1.14.0), skip this step. Instead, send your Apple invoice to this address to restore full version: ";

View File

@ -71,3 +71,5 @@
"menu.support.title" = "Supporto"; "menu.support.title" = "Supporto";
"menu.quit.title" = "Esci da %@"; "menu.quit.title" = "Esci da %@";
"menu.quit.messages.confirm" = "La VPN, se abilitata, continuerà ad essere attiva in background. Vuoi comunque uscire?"; "menu.quit.messages.confirm" = "La VPN, se abilitata, continuerà ad essere attiva in background. Vuoi comunque uscire?";
"purchase.sections.products.footer.mac_legacy" = "Se hai acquistato la vecchia app macOS (1.14.0), ignora questo passaggio. Piuttosto, inoltra la tua ricevuta Apple a questo indirizzo per ripristinare la versione completa: ";