Files
amnezia-client/client/ui/models/api/apiBenefitsModel.cpp
vkamn 78f504e35c feat: new services description (#2412)
* feat: iap for apple now use storekit2

* fix: fixed error 101 on connection event

* feat: enhance StoreKit2Helper to handle entitlements and improve restore service from App Store functionality

* chore: add isInAppPurchase and isTestPurchase in primary config

* refactor: use end_date from primary config for renew ui

* fix: hide renew button for free

* fix: hide renew button for appstore purchases

* feat: add new premium info page

* feat: add new free info page

* chore: minor fixes

* refactor: move plan and benefits into separate models

* fix: fixed expired status when configs without an end date

* feat: add trial api support

* chore: add api message parsing for 422 error

* feat: move privacy policy and term of use to gateway

* feat: add iap support for new premium info page

* chore: minor fixes

* chore: minor fix

* chore: minor fixes

* feat: additional parsing for storekit subscription plans

* chore: minor codestyle fixes

* chore: simplify benefits

* chore: hide extend buttons on external premium

* feat: add trial error processing

* fix: remove wrong check from tiral handler

* chore: cleanup

---------

Co-authored-by: spectrum <yyy@amnezia.org>
2026-04-08 12:21:12 +08:00

113 lines
3.4 KiB
C++

#include "apiBenefitsModel.h"
#include <QHash>
#include <utility>
#include <QJsonObject>
#include <QJsonValue>
namespace
{
namespace configKey
{
constexpr char title[] = "title";
constexpr char body[] = "body";
constexpr char icon[] = "icon";
constexpr char accent[] = "accent";
}
QString gatewayIconKeyToUrl(const QString &iconKey)
{
if (iconKey.startsWith(QLatin1String("qrc:"))) {
return iconKey;
}
static const QHash<QString, QString> map = {
{ QStringLiteral("globe-2"), QStringLiteral("qrc:/images/controls/globe-2.svg") },
{ QStringLiteral("smartphone"), QStringLiteral("qrc:/images/controls/smartphone.svg") },
{ QStringLiteral("gauge"), QStringLiteral("qrc:/images/controls/gauge.svg") },
{ QStringLiteral("infinity"), QStringLiteral("qrc:/images/controls/infinity.svg") },
{ QStringLiteral("tag"), QStringLiteral("qrc:/images/controls/tag.svg") },
{ QStringLiteral("history"), QStringLiteral("qrc:/images/controls/history.svg") },
{ QStringLiteral("info"), QStringLiteral("qrc:/images/controls/info.svg") },
{ QStringLiteral("app"), QStringLiteral("qrc:/images/controls/app.svg") },
{ QStringLiteral("download"), QStringLiteral("qrc:/images/controls/download.svg") },
{ QStringLiteral("help-circle"), QStringLiteral("qrc:/images/controls/help-circle.svg") },
};
return map.value(iconKey, QStringLiteral("qrc:/images/controls/info.svg"));
}
}
ApiBenefitsModel::ApiBenefitsModel(QObject *parent)
: QAbstractListModel(parent)
{
}
int ApiBenefitsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_serviceBenefits.size();
}
QVariant ApiBenefitsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_serviceBenefits.size()) {
return {};
}
const ServiceBenefitItem &item = m_serviceBenefits.at(index.row());
switch (role) {
case IconRole:
return item.icon;
case TitleRole:
return item.title;
case BodyRole:
return item.body;
case AccentRole:
return item.accent;
default:
return {};
}
}
QHash<int, QByteArray> ApiBenefitsModel::roleNames() const
{
return {
{ IconRole, "icon" },
{ TitleRole, "title" },
{ BodyRole, "body" },
{ AccentRole, "accent" },
};
}
void ApiBenefitsModel::updateModel(const QJsonArray &benefits)
{
beginResetModel();
m_serviceBenefits.clear();
for (const QJsonValue &benefitValue : benefits) {
if (!benefitValue.isObject()) {
continue;
}
const QJsonObject benefitObject = benefitValue.toObject();
QString title = benefitObject.value(configKey::title).toString();
QString body = benefitObject.value(configKey::body).toString();
const QString iconKey = benefitObject.value(configKey::icon).toString();
if (title.isEmpty() && body.isEmpty()) {
continue;
}
ServiceBenefitItem item;
item.icon = gatewayIconKeyToUrl(iconKey);
item.title = std::move(title);
item.body = std::move(body);
item.accent = benefitObject.value(configKey::accent).toBool();
m_serviceBenefits.append(std::move(item));
}
endResetModel();
}
void ApiBenefitsModel::clear()
{
beginResetModel();
m_serviceBenefits.clear();
endResetModel();
}