performance: Improve the wallet loading time

+ small bug fixes
This commit is contained in:
Alex Jbanca 2024-01-29 21:49:59 +02:00 committed by Alex Jbanca
parent a6abdbeeef
commit a55dcf299e
10 changed files with 428 additions and 107 deletions

View File

@ -26,6 +26,9 @@ QtObject:
extradata: ExtraData
traits: TraitModel
ownership: OwnershipModel
generatedId: string
generatedCollectionId: string
proc setup(self: CollectiblesEntry) =
self.QObject.setup
@ -45,32 +48,6 @@ QtObject:
self.ownership.setItems(ownership)
self.setup()
proc newCollectibleDetailsFullEntry*(data: backend.Collectible, extradata: ExtraData): CollectiblesEntry =
new(result, delete)
result.id = data.id
result.setData(data)
result.extradata = extradata
result.setup()
proc newCollectibleDetailsBasicEntry*(id: backend.CollectibleUniqueID, extradata: ExtraData): CollectiblesEntry =
new(result, delete)
result.id = id
result.extradata = extradata
result.traits = newTraitModel()
result.ownership = newOwnershipModel()
result.setup()
proc newCollectibleDetailsEmptyEntry*(): CollectiblesEntry =
let id = backend.CollectibleUniqueID(
contractID: backend.ContractID(
chainID: 0,
address: ""
),
tokenID: stint.u256(0)
)
let extradata = ExtraData()
return newCollectibleDetailsBasicEntry(id, extradata)
proc `$`*(self: CollectiblesEntry): string =
return fmt"""CollectiblesEntry(
id:{self.id},
@ -78,6 +55,8 @@ QtObject:
extradata:{self.extradata},
traits:{self.traits},
ownership:{self.ownership},
generatedId:{self.generatedId},
generatedCollectionId:{self.generatedCollectionId}
)"""
proc getCollectibleUniqueID*(self: CollectiblesEntry): backend.CollectibleUniqueID =
@ -130,10 +109,16 @@ QtObject:
# Unique ID to identify collectible, generated by us
proc getID*(self: CollectiblesEntry): string =
return self.generatedId
proc generateId*(self: CollectiblesEntry): string =
return fmt"{self.getChainId}+{self.getContractAddress}+{self.getTokenID}"
# Unique ID to identify collection, generated by us
proc getCollectionID*(self: CollectiblesEntry): string =
return self.generatedCollectionId
proc generateCollectionId*(self: CollectiblesEntry): string =
return fmt"{self.getChainId}+{self.getContractAddress}"
proc nameChanged*(self: CollectiblesEntry) {.signal.}
@ -359,4 +344,34 @@ QtObject:
self.communityColorChanged()
self.communityPrivilegesLevelChanged()
self.communityImageChanged()
return true
return true
proc newCollectibleDetailsFullEntry*(data: backend.Collectible, extradata: ExtraData): CollectiblesEntry =
new(result, delete)
result.id = data.id
result.setData(data)
result.extradata = extradata
result.generatedId = result.generateId()
result.generatedCollectionId = result.generateCollectionId()
result.setup()
proc newCollectibleDetailsBasicEntry*(id: backend.CollectibleUniqueID, extradata: ExtraData): CollectiblesEntry =
new(result, delete)
result.id = id
result.extradata = extradata
result.traits = newTraitModel()
result.ownership = newOwnershipModel()
result.generatedId = result.generateId()
result.generatedCollectionId = result.generateCollectionId()
result.setup()
proc newCollectibleDetailsEmptyEntry*(): CollectiblesEntry =
let id = backend.CollectibleUniqueID(
contractID: backend.ContractID(
chainID: 0,
address: ""
),
tokenID: stint.u256(0)
)
let extradata = ExtraData()
return newCollectibleDetailsBasicEntry(id, extradata)

View File

@ -5,6 +5,8 @@
#include <QQmlContext>
#include <QQmlExpression>
#include <QQmlScriptString>
#include <QSet>
#include <QQmlPropertyMap>
#include <memory>
@ -14,9 +16,10 @@ class FastExpressionSorter : public qqsfpm::Sorter
Q_PROPERTY(QQmlScriptString expression READ expression
WRITE setExpression NOTIFY expressionChanged)
Q_PROPERTY(QStringList expectedRoles READ expectedRoles
Q_PROPERTY(QSet<QByteArray> expectedRoles READ expectedRoles
WRITE setExpectedRoles NOTIFY expectedRolesChanged)
public:
using qqsfpm::Sorter::Sorter;
const QQmlScriptString& expression() const;
@ -24,16 +27,18 @@ public:
void proxyModelCompleted(const qqsfpm::QQmlSortFilterProxyModel& proxyModel) override;
void setExpectedRoles(const QStringList& expectedRoles);
const QStringList& expectedRoles() const;
void setExpectedRoles(const QSet<QByteArray>& expectedRoles);
const QSet<QByteArray>& expectedRoles() const;
void queueInvalidate();
void onInvalidate();
Q_SIGNALS:
void expressionChanged();
void expectedRolesChanged();
protected:
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight,
const qqsfpm::QQmlSortFilterProxyModel& proxyModel) const override;
int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const qqsfpm::QQmlSortFilterProxyModel& proxyModel) const override;
private:
void updateContext(const qqsfpm::QQmlSortFilterProxyModel& proxyModel);
@ -44,5 +49,10 @@ private:
std::unique_ptr<QQmlExpression> m_expression;
std::unique_ptr<QQmlContext> m_context;
QStringList m_expectedRoles;
QSet<QByteArray> m_expectedRoles;
bool m_queuedInvalidate { false };
mutable QQmlPropertyMap m_modelLeftMap;
mutable QQmlPropertyMap m_modelRightMap;
};

View File

@ -50,12 +50,28 @@ void FastExpressionSorter::setExpression(const QQmlScriptString& scriptString)
updateExpression();
emit expressionChanged();
invalidate();
queueInvalidate();
}
void FastExpressionSorter::queueInvalidate()
{
if (m_queuedInvalidate)
return;
m_queuedInvalidate = true;
QMetaObject::invokeMethod(this, &FastExpressionSorter::invalidate, Qt::QueuedConnection);
}
void FastExpressionSorter::onInvalidate()
{
m_queuedInvalidate = false;
Sorter::invalidate();
}
void FastExpressionSorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
{
updateContext(proxyModel);
Sorter::proxyModelCompleted(proxyModel);
}
/*!
@ -63,7 +79,7 @@ void FastExpressionSorter::proxyModelCompleted(const QQmlSortFilterProxyModel& p
List of role names intended to be available in the expression's context.
*/
void FastExpressionSorter::setExpectedRoles(const QStringList& expectedRoles)
void FastExpressionSorter::setExpectedRoles(const QSet<QByteArray>& expectedRoles)
{
if (m_expectedRoles == expectedRoles)
return;
@ -71,44 +87,45 @@ void FastExpressionSorter::setExpectedRoles(const QStringList& expectedRoles)
m_expectedRoles = expectedRoles;
emit expectedRolesChanged();
invalidate();
queueInvalidate();
}
const QStringList &FastExpressionSorter::expectedRoles() const
const QSet<QByteArray> &FastExpressionSorter::expectedRoles() const
{
return m_expectedRoles;
}
bool evaluateBoolExpression(QQmlExpression& expression)
int evaluateIntExpression(QQmlExpression& expression)
{
QVariant variantResult = expression.evaluate();
if (expression.hasError()) {
qWarning() << expression.error();
return false;
return -1;
}
if (variantResult.canConvert<bool>())
return variantResult.toBool();
if (variantResult.canConvert<int>())
return variantResult.toInt();
qWarning("%s:%i:%i : Can't convert result to bool",
qWarning("%s:%i:%i : Can't convert result to int",
expression.sourceFile().toUtf8().data(),
expression.lineNumber(),
expression.columnNumber());
return false;
return 0;
}
int FastExpressionSorter::compare(const QModelIndex& sourceLeft,
const QModelIndex& sourceRight,
const QQmlSortFilterProxyModel& proxyModel) const
const QModelIndex& sourceRight,
const QQmlSortFilterProxyModel& proxyModel) const
{
if (m_scriptString.isEmpty())
return 0;
QVariantMap modelLeftMap, modelRightMap;
if (m_scriptString.isEmpty() || !m_context || !m_expression)
return false;
m_expression->setNotifyOnValueChanged(false);
QHash<int, QByteArray> roles = proxyModel.roleNames();
QQmlContext context(qmlContext(this));
for (auto it = roles.cbegin(); it != roles.cend(); ++it) {
auto role = it.key();
auto name = it.value();
@ -116,50 +133,42 @@ int FastExpressionSorter::compare(const QModelIndex& sourceLeft,
if (!m_expectedRoles.contains(name))
continue;
modelLeftMap.insert(name, proxyModel.sourceData(sourceLeft, role));
modelRightMap.insert(name, proxyModel.sourceData(sourceRight, role));
m_modelLeftMap.insert(name, proxyModel.sourceData(sourceLeft, role));
m_modelRightMap.insert(name, proxyModel.sourceData(sourceRight, role));
}
modelLeftMap.insert(QStringLiteral("index"), sourceLeft.row());
modelRightMap.insert(QStringLiteral("index"), sourceRight.row());
m_modelLeftMap.insert(QStringLiteral("index"), sourceLeft.row());
m_modelRightMap.insert(QStringLiteral("index"), sourceRight.row());
QQmlExpression expression(m_scriptString, &context);
m_expression->setNotifyOnValueChanged(true);
context.setContextProperty(QStringLiteral("modelLeft"), modelLeftMap);
context.setContextProperty(QStringLiteral("modelRight"), modelRightMap);
if (evaluateBoolExpression(expression))
return -1;
context.setContextProperty(QStringLiteral("modelLeft"), modelRightMap);
context.setContextProperty(QStringLiteral("modelRight"), modelLeftMap);
if (evaluateBoolExpression(expression))
return 1;
return 0;
return evaluateIntExpression(*m_expression);
}
void FastExpressionSorter::updateContext(const QQmlSortFilterProxyModel& proxyModel)
{
m_context = std::make_unique<QQmlContext>(qmlContext(this));
updateExpression();
QVariantMap modelLeftMap, modelRightMap;
if (!m_expression)
return;
m_expression->setNotifyOnValueChanged(false);
const auto roleNames = proxyModel.roleNames();
for (const QByteArray& name : roleNames) {
if (!m_expectedRoles.contains(name))
continue;
modelLeftMap.insert(name, {});
modelRightMap.insert(name, {});
m_modelLeftMap.insert(name, {});
m_modelRightMap.insert(name, {});
}
modelLeftMap.insert(QStringLiteral("index"), -1);
modelRightMap.insert(QStringLiteral("index"), -1);
m_modelLeftMap.insert(QStringLiteral("index"), -1);
m_modelRightMap.insert(QStringLiteral("index"), -1);
m_context->setContextProperty(QStringLiteral("modelLeft"), modelLeftMap);
m_context->setContextProperty(QStringLiteral("modelRight"), modelRightMap);
m_context->setContextProperty(QStringLiteral("modelLeft"), &m_modelLeftMap);
m_context->setContextProperty(QStringLiteral("modelRight"), &m_modelRightMap);
updateExpression();
m_expression->setNotifyOnValueChanged(true);
}
void FastExpressionSorter::updateExpression()
@ -171,7 +180,7 @@ void FastExpressionSorter::updateExpression()
m_context.get());
connect(m_expression.get(), &QQmlExpression::valueChanged, this,
&FastExpressionSorter::invalidate);
&FastExpressionSorter::queueInvalidate);
m_expression->setNotifyOnValueChanged(true);
m_expression->evaluate();
}

View File

@ -239,8 +239,7 @@ void ManageTokensController::loadSettings()
{
Q_ASSERT(!m_settingsKey.isEmpty());
setSettingsDirty(true);
m_settingsData.clear();
SerializedTokenData result;
// load from QSettings
m_settings.beginGroup(settingsGroupName());
@ -256,7 +255,7 @@ void ManageTokensController::loadSettings()
const auto pos = m_settings.value(QStringLiteral("pos"), INT_MAX).toInt();
const auto visible = m_settings.value(QStringLiteral("visible"), true).toBool();
const auto groupId = m_settings.value(QStringLiteral("groupId")).toString();
m_settingsData.insert(symbol, {pos, visible, groupId});
result.insert(symbol, {pos, visible, groupId});
}
m_settings.endArray();
@ -277,7 +276,11 @@ void ManageTokensController::loadSettings()
setArrangeByCollection(m_settings.value(QStringLiteral("ArrangeByCollection"), false).toBool());
m_settings.endGroup();
setSettingsDirty(false);
if (result != m_settingsData) {
m_settingsData = result;
setSettingsDirty(true);
}
}
void ManageTokensController::setSettingsDirty(bool dirty)
@ -353,7 +356,7 @@ void ManageTokensController::settingsHideGroupTokens(const QString& groupId, con
saveSettings(true);
}
bool ManageTokensController::lessThan(const QString& lhsSymbol, const QString& rhsSymbol) const
int ManageTokensController::compareTokens(const QString& lhsSymbol, const QString& rhsSymbol) const
{
int leftPos, rightPos;
bool leftVisible, rightVisible;
@ -365,7 +368,11 @@ bool ManageTokensController::lessThan(const QString& lhsSymbol, const QString& r
leftPos = leftVisible ? leftPos : INT_MAX;
rightPos = rightVisible ? rightPos : INT_MAX;
return leftPos <= rightPos;
if (leftPos < rightPos)
return -1;
if (leftPos > rightPos)
return 1;
return 0;
}
bool ManageTokensController::filterAcceptsSymbol(const QString& symbol) const

View File

@ -52,7 +52,7 @@ public:
Q_INVOKABLE void settingsHideToken(const QString& symbol);
Q_INVOKABLE void settingsHideGroupTokens(const QString& groupId, const QStringList& symbols);
Q_INVOKABLE bool lessThan(const QString& lhsSymbol, const QString& rhsSymbol) const;
Q_INVOKABLE int compareTokens(const QString& lhsSymbol, const QString& rhsSymbol) const;
Q_INVOKABLE bool filterAcceptsSymbol(const QString& symbol) const;
protected:

View File

@ -17,17 +17,21 @@ Item {
property int d: 1
property alias sorterEnabled: sorter.enabled
property alias sortingAscending: sorter.ascendingOrder
property alias sorters: testModel.sorters
readonly property ListModel source: ListModel {
id: listModel
ListElement { a: 1; b: 11; c: 101 }
ListElement { a: 2; b: 12; c: 102 }
ListElement { a: 1; b: 11; c: 100 }
ListElement { a: 2; b: 11; c: 101 }
ListElement { a: 3; b: 13; c: 103 }
ListElement { a: 4; b: 14; c: 104 }
ListElement { a: 5; b: 15; c: 105 }
ListElement { a: 6; b: 16; c: 106 }
ListElement { a: 2; b: 12; c: 101 }
ListElement { a: 7; b: 17; c: 107 }
ListElement { a: 7; b: 17; c: 108 }
}
readonly property ModelAccessObserverProxy observer: ModelAccessObserverProxy {
@ -44,28 +48,71 @@ Item {
}
}
readonly property SortFilterProxyModel model: SortFilterProxyModel {
property SortFilterProxyModel model: SortFilterProxyModel {
id: testModel
sourceModel: observerProxy
sorters: FastExpressionSorter {
id: sorter
sorters: [sorter]
}
expression: {
return d ? modelLeft.a < modelRight.a
: modelLeft.a > modelRight.a
}
readonly property Component modelWithPriorityComponent: Component {
SortFilterProxyModel {
id: testModelWithPriority
expectedRoles: ["a"]
sourceModel: observerProxy
sorters: [sorter, otherSorter, roleSorter]
}
}
readonly property FastExpressionSorter sorter: FastExpressionSorter {
id: sorter
expression: {
if (modelLeft.a < modelRight.a)
return d ? -1 : 1
else if (modelLeft.a > modelRight.a)
return d ? 1 : -1
else
return 0
}
expectedRoles: ["a"]
}
readonly property FastExpressionSorter otherSorter: FastExpressionSorter {
id: otherSorter
expression: {
if (modelLeft.b > modelRight.b)
return -1
else if (modelLeft.b < modelRight.b)
return 1
else
return 0
}
expectedRoles: ["b"]
}
readonly property RoleSorter roleSorter: RoleSorter {
id: roleSorter
roleName: "c"
ascendingOrder: false
}
readonly property SignalSpy rowsRemovedSpy: SignalSpy {
target: testModel
signalName: "rowsRemoved"
}
readonly property SignalSpy layoutChangedSpy: SignalSpy {
id: layoutChangedSpy
target: testModel
signalName: "layoutChanged"
}
}
}
@ -76,17 +123,17 @@ Item {
const obj = createTemporaryObject(testComponent, root)
const count = obj.model.count
compare(count, 7)
compare(count, 9)
verify(obj.observer.accessCounter
< count * Math.ceil(Math.log2(count)) * 3)
compare(obj.observer.accessedRoles.size, 1)
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(6).a, 7)
compare(obj.model.get(7).a, 7)
}
function test_filteringAfterContextChange() {
function test_sortingAfterContextChange() {
const obj = createTemporaryObject(testComponent, root)
const count = obj.model.count
@ -98,9 +145,9 @@ Item {
< count * Math.ceil(Math.log2(count)) * 3)
compare(obj.observer.accessedRoles.size, 1)
compare(obj.model.get(0).a, 7)
compare(obj.model.get(1).a, 6)
compare(obj.model.get(6).a, 1)
tryVerify(() => obj.model.get(0).a, 7)
tryVerify(() => obj.model.get(1).a, 6)
tryVerify(() => obj.model.get(6).a, 1)
}
function test_enabled() {
@ -110,7 +157,7 @@ Item {
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(6).a, 7)
compare(obj.model.get(7).a, 7)
obj.observer.accessedRoles.clear()
obj.observer.accessCounter = 0
@ -123,8 +170,236 @@ Item {
compare(obj.observer.accessedRoles.size, 1)
compare(obj.model.get(0).a, 7)
compare(obj.model.get(1).a, 6)
compare(obj.model.get(6).a, 1)
compare(obj.model.get(1).a, 7)
compare(obj.model.get(7).a, 2)
compare(obj.model.get(8).a, 1)
}
function test_sortingDescending() {
const obj = createTemporaryObject(testComponent, root)
const count = obj.model.count
verify(obj.observer.accessCounter
< count * Math.ceil(Math.log2(count)) * 3)
compare(obj.observer.accessedRoles.size, 1)
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(7).a, 7)
obj.observer.accessCounter = 0
obj.sortingAscending = false
tryVerify(() => obj.observer.accessCounter
< count * Math.ceil(Math.log2(count)) * 3)
tryVerify(() => obj.model.get(0).a, 7)
tryVerify(() => obj.model.get(1).a, 6)
tryVerify(() => obj.model.get(7).a, 1)
}
function test_sortingDescendingAfterEnablingSorting() {
const obj = createTemporaryObject(testComponent, root, { sorterEnabled: false, sortingAscending: false })
compare(obj.observer.accessCounter, 0)
compare(obj.observer.accessedRoles.size, 0)
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(7).a, 7)
obj.observer.accessedRoles.clear()
obj.observer.accessCounter = 0
obj.sorterEnabled = true
const count = obj.model.count
verify(obj.observer.accessCounter
< count * Math.ceil(Math.log2(count)) * 3)
compare(obj.observer.accessedRoles.size, 1)
compare(obj.model.get(0).a, 7)
compare(obj.model.get(1).a, 7)
compare(obj.model.get(8).a, 1)
obj.observer.accessedRoles.clear()
obj.observer.accessCounter = 0
obj.sorterEnabled = false
verify(obj.observer.accessCounter == 0)
compare(obj.observer.accessedRoles.size, 0)
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(7).a, 7)
}
function test_stableSorting() {
const obj = createTemporaryObject(testComponent, root)
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 11)
compare(obj.model.get(2).b, 12)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
obj.sortingAscending = false
compare(obj.model.get(8).a, 1)
compare(obj.model.get(7).a, 2)
compare(obj.model.get(6).a, 2)
compare(obj.model.get(8).b, 11)
compare(obj.model.get(7).b, 12)
compare(obj.model.get(6).b, 11)
compare(obj.model.get(8).c, 100)
compare(obj.model.get(7).c, 101)
compare(obj.model.get(6).c, 101)
obj.sortingAscending = true
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 11)
compare(obj.model.get(2).b, 12)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
obj.source.append({a: 2, b: 13, c: 101})
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(3).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 11)
compare(obj.model.get(2).b, 12)
compare(obj.model.get(3).b, 13)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
compare(obj.model.get(3).c, 101)
obj.sortingAscending = false
compare(obj.model.get(9).a, 1)
compare(obj.model.get(8).a, 2)
compare(obj.model.get(7).a, 2)
compare(obj.model.get(6).a, 2)
compare(obj.model.get(9).b, 11)
compare(obj.model.get(8).b, 13)
compare(obj.model.get(7).b, 12)
compare(obj.model.get(6).b, 11)
compare(obj.model.get(9).c, 100)
compare(obj.model.get(8).c, 101)
compare(obj.model.get(7).c, 101)
compare(obj.model.get(6).c, 101)
}
function test_default_stableSorting() {
const obj = createTemporaryObject(testComponent, root, { sorters: [] })
obj.model.sortRoleName = "a"
obj.model.ascendingSortOrder = true
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 11)
compare(obj.model.get(2).b, 12)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
obj.model.ascendingSortOrder = false
compare(obj.model.get(8).a, 1)
compare(obj.model.get(7).a, 2)
compare(obj.model.get(6).a, 2)
compare(obj.model.get(8).b, 11)
compare(obj.model.get(7).b, 12)
compare(obj.model.get(6).b, 11)
compare(obj.model.get(8).c, 100)
compare(obj.model.get(7).c, 101)
compare(obj.model.get(6).c, 101)
obj.model.ascendingSortOrder = true
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 11)
compare(obj.model.get(2).b, 12)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
obj.source.append({a: 2, b: 13, c: 101})
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(3).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 11)
compare(obj.model.get(2).b, 12)
compare(obj.model.get(3).b, 13)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
compare(obj.model.get(3).c, 101)
obj.model.ascendingSortOrder = false
compare(obj.model.get(9).a, 1)
compare(obj.model.get(8).a, 2)
compare(obj.model.get(7).a, 2)
compare(obj.model.get(6).a, 2)
compare(obj.model.get(9).b, 11)
compare(obj.model.get(8).b, 13)
compare(obj.model.get(7).b, 12)
compare(obj.model.get(6).b, 11)
compare(obj.model.get(9).c, 100)
compare(obj.model.get(8).c, 101)
compare(obj.model.get(7).c, 101)
compare(obj.model.get(6).c, 101)
}
function test_sortWithPriority() {
const obj = createTemporaryObject(testComponent, root)
obj.model = createTemporaryObject(obj.modelWithPriorityComponent, obj)
compare(obj.model.get(0).a, 1)
compare(obj.model.get(1).a, 2)
compare(obj.model.get(2).a, 2)
compare(obj.model.get(0).b, 11)
compare(obj.model.get(1).b, 12) // descending "b"
compare(obj.model.get(2).b, 11)
compare(obj.model.get(0).c, 100)
compare(obj.model.get(1).c, 101)
compare(obj.model.get(2).c, 101)
compare(obj.model.get(7).a, 7)
compare(obj.model.get(8).a, 7)
compare(obj.model.get(7).c, 108) // descending "c"
compare(obj.model.get(8).c, 107)
}
}
}

View File

@ -102,7 +102,12 @@ StatusListView {
}
sorters: FastExpressionSorter {
expression: {
return modelLeft.enabledNetworkBalance > modelRight.enabledNetworkBalance // descending, biggest first
if (modelLeft.enabledNetworkBalance > modelRight.enabledNetworkBalance)
return -1 // descending, biggest first
else if (modelLeft.enabledNetworkBalance < modelRight.enabledNetworkBalance)
return 1
else
return 0
}
expectedRoles: ["enabledNetworkBalance"]
}

View File

@ -133,7 +133,7 @@ ColumnLayout {
FastExpressionSorter {
expression: {
d.controller.settingsDirty
return d.controller.lessThan(modelLeft.symbol, modelRight.symbol)
return d.controller.compareTokens(modelLeft.symbol, modelRight.symbol)
}
enabled: d.isCustomView
expectedRoles: ["symbol"]

View File

@ -131,7 +131,6 @@ RightTabBaseView {
case 2: return historyView
}
}
active: visible
Component {
id: assetsView

View File

@ -140,7 +140,7 @@ ColumnLayout {
FastExpressionSorter {
expression: {
d.controller.settingsDirty
return d.controller.lessThan(modelLeft.symbol, modelRight.symbol)
return d.controller.compareTokens(modelLeft.symbol, modelRight.symbol)
}
enabled: d.isCustomView
expectedRoles: ["symbol"]
@ -175,6 +175,7 @@ ColumnLayout {
Layout.preferredHeight: root.filterVisible ? implicitHeight : 0
spacing: 20
opacity: root.filterVisible ? 1 : 0
visible: opacity > 0
Behavior on Layout.preferredHeight { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }