mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-25 22:21:16 +00:00
feat(wallet): humanize shared wallet experience
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
#include "WalletAccountModel.h"
|
||||
|
||||
#include "WalletAccountId.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
const QString DEFAULT_PROGRAM_OWNER(64, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
WalletAccountModel::WalletAccountModel(QObject* parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
@@ -21,10 +29,36 @@ QVariant WalletAccountModel::data(const QModelIndex& index, int role) const
|
||||
return account.name;
|
||||
case AddressRole:
|
||||
return account.address;
|
||||
case DisplayAddressRole:
|
||||
return account.displayAddress;
|
||||
case BalanceRole:
|
||||
return account.balance;
|
||||
case IsPublicRole:
|
||||
return account.isPublic;
|
||||
case KindRole:
|
||||
return account.kind;
|
||||
case SectionRole:
|
||||
return account.section;
|
||||
case ProgramOwnerRole:
|
||||
return account.programOwner;
|
||||
case ReadStatusRole:
|
||||
return account.readStatus;
|
||||
case ProgramNameRole:
|
||||
return account.programName;
|
||||
case AccountTypeRole:
|
||||
return account.accountType;
|
||||
case VisibilityRole:
|
||||
return account.isPublic ? QStringLiteral("public") : QStringLiteral("private");
|
||||
case ControlRole:
|
||||
return QStringLiteral("wallet");
|
||||
case CanBePrimaryRole:
|
||||
return account.canBePrimary;
|
||||
case IsPrimaryRole:
|
||||
return account.isPrimary;
|
||||
case DefinitionIdRole:
|
||||
return account.definitionId;
|
||||
case AliasRole:
|
||||
return account.alias;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
@@ -37,25 +71,170 @@ QHash<int, QByteArray> WalletAccountModel::roleNames() const
|
||||
{ AddressRole, "address" },
|
||||
{ BalanceRole, "balance" },
|
||||
{ IsPublicRole, "isPublic" },
|
||||
{ KindRole, "kind" },
|
||||
{ SectionRole, "section" },
|
||||
{ ProgramOwnerRole, "programOwner" },
|
||||
{ ReadStatusRole, "readStatus" },
|
||||
{ ProgramNameRole, "programName" },
|
||||
{ AccountTypeRole, "accountType" },
|
||||
{ VisibilityRole, "visibility" },
|
||||
{ ControlRole, "control" },
|
||||
{ CanBePrimaryRole, "canBePrimary" },
|
||||
{ IsPrimaryRole, "isPrimary" },
|
||||
{ DefinitionIdRole, "definitionId" },
|
||||
{ AliasRole, "alias" },
|
||||
{ DisplayAddressRole, "displayAddress" },
|
||||
};
|
||||
}
|
||||
|
||||
void WalletAccountModel::replaceAccounts(const QVector<WalletAccount>& accounts)
|
||||
void WalletAccountModel::replaceAccounts(const QVector<WalletAccount>& accounts,
|
||||
const QHash<QString, QString>& aliases,
|
||||
const QString& primaryAddress)
|
||||
{
|
||||
beginResetModel();
|
||||
const qsizetype oldCount = m_accounts.size();
|
||||
m_accounts.clear();
|
||||
m_accounts.reserve(accounts.size());
|
||||
for (qsizetype index = 0; index < accounts.size(); ++index) {
|
||||
const WalletAccount& account = accounts.at(index);
|
||||
m_accounts.append({
|
||||
QStringLiteral("Account %1").arg(index + 1),
|
||||
account.address,
|
||||
account.balance,
|
||||
account.isPublic,
|
||||
});
|
||||
for (const WalletAccount& account : accounts) {
|
||||
Entry entry;
|
||||
entry.alias = aliases.value(account.address);
|
||||
entry.address = account.address;
|
||||
entry.displayAddress = walletAccountIdToBase58(account.address);
|
||||
if (entry.displayAddress.isEmpty())
|
||||
entry.displayAddress = account.address;
|
||||
entry.balance = account.balance;
|
||||
entry.isPublic = account.isPublic;
|
||||
entry.programOwner = account.programOwner;
|
||||
entry.readStatus = account.readStatus;
|
||||
if (!account.isPublic) {
|
||||
entry.kind = QStringLiteral("private");
|
||||
entry.canBePrimary = true;
|
||||
} else if (account.readStatus != QStringLiteral("ok")) {
|
||||
entry.kind = QStringLiteral("unknown");
|
||||
} else if (account.programOwner == DEFAULT_PROGRAM_OWNER) {
|
||||
entry.kind = QStringLiteral("user");
|
||||
entry.canBePrimary = true;
|
||||
} else {
|
||||
entry.kind = QStringLiteral("program");
|
||||
}
|
||||
entry.section = sectionFor(entry);
|
||||
entry.isPrimary = account.address == primaryAddress && entry.canBePrimary;
|
||||
updateEntryName(entry);
|
||||
m_accounts.append(std::move(entry));
|
||||
}
|
||||
endResetModel();
|
||||
if (oldCount != m_accounts.size())
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
void WalletAccountModel::applyPresentations(
|
||||
const QVector<WalletAccountPresentation>& presentations)
|
||||
{
|
||||
for (const WalletAccountPresentation& presentation : presentations) {
|
||||
const int row = indexOf(presentation.address);
|
||||
if (row < 0)
|
||||
continue;
|
||||
Entry& entry = m_accounts[row];
|
||||
if (!presentation.kind.isEmpty())
|
||||
entry.kind = presentation.kind;
|
||||
entry.programName = presentation.programName;
|
||||
entry.accountType = presentation.accountType;
|
||||
entry.definitionId = presentation.definitionId;
|
||||
entry.semanticName = presentation.semanticName;
|
||||
entry.section = sectionFor(entry, presentation.hiddenFromAccounts);
|
||||
entry.canBePrimary = entry.kind == QStringLiteral("user")
|
||||
|| entry.kind == QStringLiteral("private");
|
||||
if (!entry.canBePrimary)
|
||||
entry.isPrimary = false;
|
||||
updateEntryName(entry);
|
||||
const QModelIndex changed = index(row);
|
||||
emit dataChanged(changed, changed);
|
||||
}
|
||||
}
|
||||
|
||||
void WalletAccountModel::setAlias(const QString& address, const QString& alias)
|
||||
{
|
||||
const int row = indexOf(address);
|
||||
if (row < 0)
|
||||
return;
|
||||
Entry& entry = m_accounts[row];
|
||||
entry.alias = alias;
|
||||
updateEntryName(entry);
|
||||
emit dataChanged(index(row), index(row), { NameRole, AliasRole });
|
||||
}
|
||||
|
||||
void WalletAccountModel::setPrimaryAddress(const QString& address)
|
||||
{
|
||||
for (int row = 0; row < m_accounts.size(); ++row) {
|
||||
Entry& entry = m_accounts[row];
|
||||
const bool next = entry.address == address && entry.canBePrimary;
|
||||
if (entry.isPrimary == next)
|
||||
continue;
|
||||
entry.isPrimary = next;
|
||||
emit dataChanged(index(row), index(row), { IsPrimaryRole });
|
||||
}
|
||||
}
|
||||
|
||||
bool WalletAccountModel::contains(const QString& address) const
|
||||
{
|
||||
return indexOf(address) >= 0;
|
||||
}
|
||||
|
||||
bool WalletAccountModel::canBePrimary(const QString& address) const
|
||||
{
|
||||
const int row = indexOf(address);
|
||||
return row >= 0 && m_accounts.at(row).canBePrimary;
|
||||
}
|
||||
|
||||
QString WalletAccountModel::firstAutomaticPrimary() const
|
||||
{
|
||||
for (const Entry& entry : m_accounts) {
|
||||
if (entry.kind == QStringLiteral("user"))
|
||||
return entry.address;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int WalletAccountModel::indexOf(const QString& address) const
|
||||
{
|
||||
for (int row = 0; row < m_accounts.size(); ++row) {
|
||||
if (m_accounts.at(row).address == address)
|
||||
return row;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString WalletAccountModel::defaultName(const Entry& entry)
|
||||
{
|
||||
if (!entry.accountType.isEmpty()) {
|
||||
QString name = entry.accountType;
|
||||
for (qsizetype index = 1; index < name.size(); ++index) {
|
||||
if (name.at(index).isUpper() && name.at(index - 1).isLower())
|
||||
name.insert(index++, QLatin1Char(' '));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
if (entry.kind == QStringLiteral("user"))
|
||||
return QStringLiteral("User account");
|
||||
if (entry.kind == QStringLiteral("private"))
|
||||
return QStringLiteral("Private account");
|
||||
if (entry.kind == QStringLiteral("unknown"))
|
||||
return QStringLiteral("Unknown account");
|
||||
return QStringLiteral("Program account");
|
||||
}
|
||||
|
||||
QString WalletAccountModel::sectionFor(const Entry& entry, bool hiddenFromAccounts)
|
||||
{
|
||||
if (hiddenFromAccounts || entry.kind == QStringLiteral("token_holding"))
|
||||
return QStringLiteral("hidden");
|
||||
if (entry.kind == QStringLiteral("user") || entry.kind == QStringLiteral("private"))
|
||||
return QStringLiteral("accounts");
|
||||
return QStringLiteral("advanced");
|
||||
}
|
||||
|
||||
void WalletAccountModel::updateEntryName(Entry& entry)
|
||||
{
|
||||
entry.name = !entry.alias.isEmpty()
|
||||
? entry.alias
|
||||
: (!entry.semanticName.isEmpty() ? entry.semanticName : defaultName(entry));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user