feat: move privacy policy and term of use to gateway

This commit is contained in:
vkamn
2026-03-30 19:21:27 +08:00
parent 2db1416d9f
commit 285b9344c4
10 changed files with 86 additions and 56 deletions

View File

@@ -61,6 +61,8 @@ namespace apiDefs
constexpr QLatin1String endDate("end_date");
constexpr QLatin1String issuedConfigs("issued_configs");
constexpr QLatin1String subscriptionDescription("subscription_description");
constexpr QLatin1String termsOfUseUrl("terms_of_use_url");
constexpr QLatin1String privacyPolicyUrl("privacy_policy_url");
constexpr QLatin1String supportInfo("support_info");
constexpr QLatin1String email("email");

View File

@@ -3,6 +3,7 @@
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
namespace
{
@@ -10,6 +11,18 @@ namespace
constexpr QLatin1String unprocessableSubscriptionMessage("Failed to retrieve subscription information. Is it activated?");
QDateTime subscriptionEndUtcFromString(const QString &subscriptionEndDate)
{
if (subscriptionEndDate.isEmpty()) {
return {};
}
QDateTime endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODateWithMs).toUTC();
if (!endDate.isValid()) {
endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODate).toUTC();
}
return endDate;
}
QString apiErrorMessageFromJson(const QJsonObject &jsonObj)
{
const QJsonValue value = jsonObj.value(QStringLiteral("message"));
@@ -35,11 +48,11 @@ bool apiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
if (subscriptionEndDate.isEmpty()) {
return false;
}
const QDateTime endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODate).toUTC();
const QDateTime endDate = subscriptionEndUtcFromString(subscriptionEndDate);
if (!endDate.isValid()) {
return false;
}
return endDate < QDateTime::currentDateTimeUtc();
return endDate <= QDateTime::currentDateTimeUtc();
}
bool apiUtils::isSubscriptionExpiringSoon(const QString &subscriptionEndDate, int withinDays)
@@ -47,12 +60,12 @@ bool apiUtils::isSubscriptionExpiringSoon(const QString &subscriptionEndDate, in
if (subscriptionEndDate.isEmpty()) {
return false;
}
const QDateTime endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODate).toUTC();
const QDateTime endDate = subscriptionEndUtcFromString(subscriptionEndDate);
if (!endDate.isValid()) {
return false;
}
const QDateTime nowUtc = QDateTime::currentDateTimeUtc();
if (endDate < nowUtc) {
if (endDate <= nowUtc) {
return false;
}
return endDate <= nowUtc.addDays(withinDays);

View File

@@ -457,7 +457,7 @@ bool ApiConfigsController::importService()
if (m_apiServicesModel->getSelectedServiceType() == serviceType::amneziaPremium) {
if (isIosOrMacOsNe) {
return importSerivceFromAppStore();
return importServiceFromAppStore();
}
} else if (m_apiServicesModel->getSelectedServiceType() == serviceType::amneziaFree) {
importFreeFromGateway();
@@ -466,7 +466,7 @@ bool ApiConfigsController::importService()
return false;
}
bool ApiConfigsController::importSerivceFromAppStore()
bool ApiConfigsController::importServiceFromAppStore()
{
#if defined(Q_OS_IOS) || defined(MACOS_NE)
bool purchaseOk = false;
@@ -533,7 +533,7 @@ bool ApiConfigsController::importSerivceFromAppStore()
return true;
}
bool ApiConfigsController::restoreSerivceFromAppStore()
bool ApiConfigsController::restoreServiceFromAppStore()
{
#if defined(Q_OS_IOS) || defined(MACOS_NE)
const QString premiumServiceType = QStringLiteral("amnezia-premium");

View File

@@ -31,8 +31,8 @@ public slots:
bool fillAvailableServices();
bool importService();
bool importSerivceFromAppStore();
bool restoreSerivceFromAppStore();
bool importServiceFromAppStore();
bool restoreServiceFromAppStore();
bool importFreeFromGateway();
bool importTrialFromGateway(const QString &email);
bool updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,

View File

@@ -127,6 +127,12 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
case EndDateRole: {
return QDateTime::fromString(apiServiceData.subscription.endDate, Qt::ISODate).toLocalTime().toString("d MMM yyyy");
}
case TermsOfUseUrlRole: {
return apiServiceData.serviceInfo.termsOfUseUrl;
}
case PrivacyPolicyUrlRole: {
return apiServiceData.serviceInfo.privacyPolicyUrl;
}
case OrderRole: {
if (serviceType == serviceType::amneziaPremium) {
return 0;
@@ -260,6 +266,8 @@ QHash<int, QByteArray> ApiServicesModel::roleNames() const
roles[FeaturesRole] = "features";
roles[PriceRole] = "price";
roles[EndDateRole] = "endDate";
roles[TermsOfUseUrlRole] = "termsOfUseUrl";
roles[PrivacyPolicyUrlRole] = "privacyPolicyUrl";
roles[OrderRole] = "order";
return roles;
@@ -285,6 +293,8 @@ ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJs
serviceData.serviceInfo.cardDescription = serviceDescription.value(configKey::cardDescription).toString();
serviceData.serviceInfo.description = serviceDescription.value(configKey::description).toString();
serviceData.serviceInfo.features = serviceDescription.value(configKey::features).toString();
serviceData.serviceInfo.termsOfUseUrl = serviceDescription.value(apiDefs::key::termsOfUseUrl).toString();
serviceData.serviceInfo.privacyPolicyUrl = serviceDescription.value(apiDefs::key::privacyPolicyUrl).toString();
serviceData.subscriptionPlansJson = serviceDescription.value(configKey::subscriptionPlans).toArray();
serviceData.benefits = serviceDescription.value(configKey::benefits).toArray();

View File

@@ -23,6 +23,9 @@ public:
QString features;
QString cardDescription;
QString termsOfUseUrl;
QString privacyPolicyUrl;
QJsonObject object;
};
@@ -60,6 +63,8 @@ public:
FeaturesRole,
PriceRole,
EndDateRole,
TermsOfUseUrlRole,
PrivacyPolicyUrlRole,
OrderRole
};

View File

@@ -12,7 +12,7 @@ QtObject {
readonly property color slateGray: '#2C2D30'
readonly property color onyxBlack: '#1C1D21'
readonly property color midnightBlack: '#0E0E11'
readonly property color goldenApricot: '#FBB26A'
readonly property color goldenApricot: goldenApricotString
readonly property color benefitsPanelBackground: '#1C1C1E'
readonly property color softViolet: '#A87BE2'
readonly property color burntOrange: '#A85809'
@@ -21,6 +21,8 @@ QtObject {
readonly property color deepBrown: '#402102'
readonly property color vibrantRed: '#EB5757'
readonly property color darkCharcoal: '#261E1A'
readonly property color pearlGray: '#EAEAEC'
readonly property color sheerWhite: Qt.rgba(1, 1, 1, 0.12)
readonly property color translucentWhite: Qt.rgba(1, 1, 1, 0.08)
readonly property color barelyTranslucentWhite: Qt.rgba(1, 1, 1, 0.05)
@@ -28,9 +30,10 @@ QtObject {
readonly property color softGoldenApricot: Qt.rgba(251/255, 178/255, 106/255, 0.3)
readonly property color mistyGray: Qt.rgba(215/255, 216/255, 219/255, 0.8)
readonly property color cloudyGray: Qt.rgba(215/255, 216/255, 219/255, 0.65)
readonly property color pearlGray: '#EAEAEC'
readonly property color translucentRichBrown: Qt.rgba(99/255, 51/255, 3/255, 0.26)
readonly property color translucentSlateGray: Qt.rgba(85/255, 86/255, 92/255, 0.13)
readonly property color translucentOnyxBlack: Qt.rgba(28/255, 29/255, 33/255, 0.13)
readonly property string goldenApricotString: '#FBB26A'
}
}

View File

@@ -124,10 +124,10 @@ PageType {
font.pixelSize: 12
text: {
var termsUrl = LanguageModel.getCurrentSiteUrl()
var privacyUrl = LanguageModel.getCurrentSiteUrl("policy")
return qsTr("By continuing, you agree to the <a href=\"%1\" style=\"color: %3;\">Terms of Use</a> and <a href=\"%2\" style=\"color: %3;\">Privacy Policy</a>")
.arg(termsUrl).arg(privacyUrl).arg("#FBB26A")
.arg(String(ApiServicesModel.getSelectedServiceData("termsOfUseUrl")))
.arg(String(ApiServicesModel.getSelectedServiceData("privacyPolicyUrl")))
.arg(AmneziaStyle.color.goldenApricotString)
}
onLinkActivated: function(link) {
@@ -158,7 +158,7 @@ PageType {
var termsUrl = "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/"
var privacyUrl = LanguageModel.getCurrentSiteUrl("policy")
return qsTr("By continuing, you agree to the <a href=\"%1\" style=\"color: %3;\">Terms of Use</a> and <a href=\"%2\" style=\"color: %3;\">Privacy Policy</a>")
.arg(termsUrl).arg(privacyUrl).arg("#FBB26A")
.arg(termsUrl).arg(privacyUrl).arg(AmneziaStyle.color.goldenApricotString)
}
onLinkActivated: function(link) {

View File

@@ -114,50 +114,47 @@ PageType {
benefitsModel: ApiBenefitsModel
}
ParagraphTextType {
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
Layout.bottomMargin: 24
visible: Qt.platform.os === "ios" || IsMacOsNeBuild
spacing: 16
visible: (Qt.platform.os === "ios" || IsMacOsNeBuild)
ParagraphTextType {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
textFormat: Text.PlainText
color: AmneziaStyle.color.mutedGray
font.pixelSize: 12
horizontalAlignment: Text.AlignHCenter
textFormat: Text.PlainText
color: AmneziaStyle.color.mutedGray
font.pixelSize: 12
text: qsTr("Charged to your Apple ID at confirmation. Renews automatically unless auto-renew is turned off at least 24 hours before period end. Manage in Apple ID settings.")
}
ParagraphTextType {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
visible: !(Qt.platform.os === "ios" || IsMacOsNeBuild)
horizontalAlignment: Text.AlignHCenter
textFormat: Text.RichText
color: AmneziaStyle.color.mutedGray
font.pixelSize: 12
text: {
var termsUrl = LanguageModel.getCurrentSiteUrl()
var privacyUrl = LanguageModel.getCurrentSiteUrl("policy")
return qsTr("By continuing, you agree to the <a href=\"%1\" style=\"color: %3;\">Terms of Use</a> and <a href=\"%2\" style=\"color: %3;\">Privacy Policy</a>")
.arg(termsUrl).arg(privacyUrl).arg("#FBB26A")
text: qsTr("Charged to your Apple ID at confirmation. Renews automatically unless auto-renew is turned off at least 24 hours before period end. Manage in Apple ID settings.")
}
onLinkActivated: function(link) {
Qt.openUrlExternally(link)
}
ParagraphTextType {
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
textFormat: Text.RichText
color: AmneziaStyle.color.mutedGray
font.pixelSize: 12
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
text: {
var termsUrl = "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/"
var privacyUrl = LanguageModel.getCurrentSiteUrl("policy")
return qsTr("By continuing, you agree to the <a href=\"%1\" style=\"color: %3;\">Terms of Use</a> and <a href=\"%2\" style=\"color: %3;\">Privacy Policy</a>")
.arg(termsUrl).arg(privacyUrl).arg(AmneziaStyle.color.goldenApricotString)
}
onLinkActivated: function(link) {
Qt.openUrlExternally(link)
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
}
}
@@ -167,7 +164,7 @@ PageType {
Layout.rightMargin: 16
Layout.bottomMargin: 24
visible: (Qt.platform.os === "ios" || IsMacOsNeBuild)
visible: !(Qt.platform.os === "ios" || IsMacOsNeBuild)
horizontalAlignment: Text.AlignHCenter
textFormat: Text.RichText
@@ -175,10 +172,10 @@ PageType {
font.pixelSize: 12
text: {
var termsUrl = "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/"
var privacyUrl = LanguageModel.getCurrentSiteUrl("policy")
return qsTr("By continuing, you agree to the <a href=\"%1\" style=\"color: %3;\">Terms of Use</a> and <a href=\"%2\" style=\"color: %3;\">Privacy Policy</a>")
.arg(termsUrl).arg(privacyUrl).arg("#FBB26A")
.arg(String(ApiServicesModel.getSelectedServiceData("termsOfUseUrl")))
.arg(String(ApiServicesModel.getSelectedServiceData("privacyPolicyUrl")))
.arg(AmneziaStyle.color.goldenApricotString)
}
onLinkActivated: function(link) {

View File

@@ -361,7 +361,7 @@ PageType {
property bool isVisible: Qt.platform.os === "ios" || IsMacOsNeBuild
property var handler: function() {
PageController.showBusyIndicator(true)
ApiConfigsController.restoreSerivceFromAppStore()
ApiConfigsController.restoreServiceFromAppStore()
PageController.showBusyIndicator(false)
}
}