feat: ios in-app purchase methods (#1652)

* Add in-app purchase methods

* fix: init StoreKit controller on startup

* fix: Add transaction details to StoreKit callbacks

* nullpointer access fixed

* feat: in app purchase for ios

* feat: add IAP product fetching and logging for iOS platform

* feat: iOS Simulator building pipeline made

* feat: add support for multiple IAP product IDs and attempt purchase of the first valid one

* feat: add support for retrieving Base64-encoded app receipt after successful IAP purchase

* refactor: inapp-purchase code cleanup

* feat: iap processing

* refactor: move to storekit 2

* feat: add request to billing

* chore: add ios ifdef

* feat: remove iOS simulator specific code and exclusions

* refactor: remove unused StoreKit 2 transaction observer and simplify IAP product fetching logic

* feat: implement StoreKit 2 for iOS and macOS, add restore purchases functionality

* fix: Restore Purchases button appearance updated

* feat: enhance error handling and duplicate config detection in ApiConfigsController

* feat: add support for Mac OS NE in-app purchases and StoreKitController

* ci-cd fix

* Revert "ci-cd fix"

This reverts commit f22fd7a13b.

---------

Co-authored-by: vladimir.kuznetsov <nethiuswork@gmail.com>
Co-authored-by: vkamn <vk@amnezia.org>
Co-authored-by: spectrum <yyy@amnezia.org>
This commit is contained in:
Yaroslav
2025-12-18 16:36:12 +02:00
committed by GitHub
parent 46ce22b85c
commit 6178b05643
22 changed files with 910 additions and 14 deletions
@@ -106,14 +106,18 @@ PageType {
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Connect")
clickedFunc: function() {
var endpoint = ApiServicesModel.getStoreEndpoint()
if (endpoint !== undefined && endpoint !== "") {
Qt.openUrlExternally(endpoint)
PageController.closePage()
PageController.closePage()
text: qsTr("Connect")
clickedFunc: function() {
var endpoint = ApiServicesModel.getStoreEndpoint()
if (endpoint !== undefined && endpoint !== "" && Qt.platform.os !== "ios" && !IsMacOsNeBuild) {
Qt.openUrlExternally(endpoint)
PageController.closePage()
PageController.closePage()
} else if (Qt.platform.os === "ios" || IsMacOsNeBuild) {
PageController.showBusyIndicator(true)
ApiConfigsController.importSerivceFromAppStore()
PageController.showBusyIndicator(false)
} else {
PageController.showBusyIndicator(true)
ApiConfigsController.importServiceFromGateway()
@@ -242,7 +242,7 @@ PageType {
Layout.alignment: Qt.AlignHCenter
implicitHeight: 32
visible: Qt.platform.os !== "ios"
visible: Qt.platform.os !== "ios" && !IsMacOsNeBuild
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.translucentWhite
@@ -267,6 +267,7 @@ PageType {
backupRestore,
fileOpen,
qrScan,
restorePurchases,
siteLink
]
@@ -351,13 +352,27 @@ PageType {
}
}
QtObject {
id: restorePurchases
property string title: qsTr("Restore purchases")
property string description: qsTr("")
property string imageSource: "qrc:/images/controls/refresh-cw.svg"
property bool isVisible: Qt.platform.os === "ios" || IsMacOsNeBuild
property var handler: function() {
PageController.showBusyIndicator(true)
ApiConfigsController.restoreSerivceFromAppStore()
PageController.showBusyIndicator(false)
}
}
QtObject {
id: siteLink
property string title: qsTr("I have nothing")
property string description: qsTr("")
property string imageSource: "qrc:/images/controls/help-circle.svg"
property bool isVisible: PageController.isStartPageVisible() && Qt.platform.os !== "ios"
property bool isVisible: PageController.isStartPageVisible() && Qt.platform.os !== "ios" && !IsMacOsNeBuild
property var handler: function() {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
}