From 6f3a180f41ad61cffac9abdfb747d9c5e604a93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Thu, 11 Jan 2024 14:59:13 +0100 Subject: [PATCH] feat: Emit notifications when an asset/collectible is hidden in the settings - emit the signal from the backend - trigger the toast notification in QML - update the test(s) Fixes #12704 --- .../tests/tst_ManageCollectiblesPanel.qml | 36 ++++++++++--------- .../src/wallet/managetokenscontroller.cpp | 31 ++++++++++------ .../src/wallet/managetokenscontroller.h | 8 ++++- ui/StatusQ/src/wallet/managetokensmodel.cpp | 3 -- .../Wallet/controls/ManageTokensDelegate.qml | 14 ++++++-- .../controls/ManageTokensGroupDelegate.qml | 5 ++- .../Wallet/panels/ManageAssetsPanel.qml | 6 ++++ .../Wallet/panels/ManageCollectiblesPanel.qml | 6 ++++ 8 files changed, 75 insertions(+), 34 deletions(-) diff --git a/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml b/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml index a25c70bce4..afcdb95faf 100644 --- a/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml +++ b/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml @@ -6,6 +6,7 @@ import AppLayouts.Wallet.panels 1.0 import Storybook 1.0 import Models 1.0 +import utils 1.0 Item { id: root @@ -25,6 +26,12 @@ Item { } } + SignalSpy { + id: notificationSpy + target: Global + signalName: "displayToastMessage" + } + TestCase { name: "ManageCollectiblesPanel" when: windowShown @@ -65,6 +72,8 @@ Item { function init() { controlUnderTest = createTemporaryObject(componentUnderTest, root) + controlUnderTest.clearSettings() + notificationSpy.clear() } function test_showHideToken() { @@ -82,9 +91,10 @@ Item { const delegate0 = findChild(lvRegular, "manageTokensDelegate-0") verify(!!delegate0) const title = delegate0.title + tryCompare(notificationSpy, "count", 0) triggerDelegateMenuAction(lvRegular, 0, "miHideToken") - - verify(controlUnderTest.dirty) + // verify the signal to show the notification toast got fired + tryCompare(notificationSpy, "count", 1) // verify we now have +1 hidden and -1 regular tokens after the "hide" operation waitForItemPolished(lvHidden) @@ -107,8 +117,6 @@ Item { verify(!!delegateN) const titleN = delegateN.title compare(title, titleN) - - verify(controlUnderTest.dirty) } function test_showHideCommunityGroup() { @@ -125,9 +133,10 @@ Item { // verify we have 2 community collectible groups tryCompare(lvCommunityTokenGroups, "count", 3) + tryCompare(notificationSpy, "count", 0) triggerDelegateMenuAction(lvCommunityTokenGroups, 0, "miHideTokenGroup", true) - - verify(controlUnderTest.dirty) + // verify the signal to show the notification toast got fired + tryCompare(notificationSpy, "count", 1) // verify we have one less group waitForItemPolished(lvCommunityTokenGroups) @@ -136,8 +145,6 @@ Item { verify(!!lvHidden) tryCompare(lvHidden, "count", 4) // we've just hidden 4 collectibles coming from this group - verify(controlUnderTest.dirty) - // verify hidden items are not draggable const hiddenToken = findChild(lvHidden, "manageTokensDelegate-0") verify(!!hiddenToken) @@ -152,21 +159,15 @@ Item { waitForItemPolished(lvHidden) triggerDelegateMenuAction(lvHidden, 0, "miShowToken") - verify(controlUnderTest.dirty) - // verify we again have 3 community groups, and one less hidden token tryCompare(lvCommunityTokenGroups, "count", 3) tryCompare(lvHidden, "count", 3) - verify(controlUnderTest.dirty) - // now mass show tokens from this group, verify we have 0 hidden tokens and 2 visible groups triggerDelegateMenuAction(lvHidden, 0, "miShowTokenGroup") waitForItemPolished(lvHidden) tryCompare(lvHidden, "count", 0) tryCompare(lvCommunityTokenGroups, "count", 3) - - verify(controlUnderTest.dirty) } function test_dnd() { @@ -258,8 +259,10 @@ Item { // find the 2385 delegate from the Bearz group and hide it const bear2385DelegateIdx = findDelegateIndexWithTitle(bearzChildLV, "KILLABEAR #2385") verify(bear2385DelegateIdx !== -1) + tryCompare(notificationSpy, "count", 0) triggerDelegateMenuAction(bearzChildLV, bear2385DelegateIdx, "miHideCommunityToken") - verify(controlUnderTest.dirty) + // verify the signal to show the notification toast got fired + tryCompare(notificationSpy, "count", 1) // verify the hidden section now has 1 item and it's the one we just hid const lvHidden = findChild(controlUnderTest, "lvHiddenTokens") @@ -282,7 +285,8 @@ Item { verify(!!pandasChildLV) const panda909DelegateIdx = findDelegateIndexWithTitle(pandasChildLV, "Frenly Panda #909") triggerDelegateMenuAction(pandasChildLV, panda909DelegateIdx, "miHideCommunityToken") - verify(controlUnderTest.dirty) + // verify the signal to show the notification toast got fired + tryCompare(notificationSpy, "count", 2) // finally verify that the Bearz group is still at top waitForItemPolished(lvCommunityTokenGroups) diff --git a/ui/StatusQ/src/wallet/managetokenscontroller.cpp b/ui/StatusQ/src/wallet/managetokenscontroller.cpp index 52befe7096..0b4f536ac9 100644 --- a/ui/StatusQ/src/wallet/managetokenscontroller.cpp +++ b/ui/StatusQ/src/wallet/managetokenscontroller.cpp @@ -26,7 +26,7 @@ ManageTokensController::ManageTokensController(QObject* parent) #ifdef QT_DEBUG QElapsedTimer t; t.start(); - qCInfo(manageTokens) << "!!! ADDING" << last-first+1 << "NEW TOKENS"; + qCDebug(manageTokens) << "!!! ADDING" << last-first+1 << "NEW TOKENS"; #endif for (int i = first; i <= last; i++) addItem(i); @@ -36,7 +36,7 @@ ManageTokensController::ManageTokensController(QObject* parent) rebuildCommunityTokenGroupsModel(); rebuildRegularTokenGroupsModel(); #ifdef QT_DEBUG - qCInfo(manageTokens) << "!!! ADDING NEW SOURCE DATA TOOK" << t.nsecsElapsed()/1'000'000.f << "ms"; + qCDebug(manageTokens) << "!!! ADDING NEW SOURCE DATA TOOK" << t.nsecsElapsed()/1'000'000.f << "ms"; #endif }); connect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &ManageTokensController::parseSourceModel); @@ -50,7 +50,6 @@ ManageTokensController::ManageTokensController(QObject* parent) }); connect(m_communityTokenGroupsModel, &ManageTokensModel::rowsMoved, this, [this](const QModelIndex &parent, int start, int end, const QModelIndex &destination, int toRow) { qCDebug(manageTokens) << "!!! GROUP MOVED FROM" << start << "TO" << toRow; - // FIXME swap toRow<->start instead of reloadCommunityIds()? reloadCommunityIds(); m_communityTokensModel->setCommunityIds(m_communityIds); m_communityTokensModel->saveCustomSortOrder(); @@ -64,12 +63,16 @@ void ManageTokensController::showHideRegularToken(int row, bool flag) { if (flag) { // show auto hiddenItem = m_hiddenTokensModel->takeItem(row); - if (hiddenItem) + if (hiddenItem) { m_regularTokensModel->addItem(*hiddenItem); + emit tokenShown(hiddenItem->symbol, hiddenItem->name); + } } else { // hide auto shownItem = m_regularTokensModel->takeItem(row); - if (shownItem) + if (shownItem) { m_hiddenTokensModel->addItem(*shownItem, false /*prepend*/); + emit tokenHidden(shownItem->symbol, shownItem->name); + } } } @@ -81,6 +84,7 @@ void ManageTokensController::showHideCommunityToken(int row, bool flag) m_communityTokensModel->addItem(*hiddenItem); if (!m_communityIds.contains(hiddenItem->communityId)) m_communityIds.append(hiddenItem->communityId); + emit tokenShown(hiddenItem->symbol, hiddenItem->name); } } else { // hide auto shownItem = m_communityTokensModel->takeItem(row); @@ -88,6 +92,7 @@ void ManageTokensController::showHideCommunityToken(int row, bool flag) m_hiddenTokensModel->addItem(*shownItem, false /*prepend*/); if (!m_communityTokensModel->hasCommunityIdToken(shownItem->communityId)) m_communityIds.removeAll(shownItem->communityId); + emit tokenHidden(shownItem->symbol, shownItem->name); } } m_communityTokensModel->setCommunityIds(m_communityIds); @@ -99,14 +104,20 @@ void ManageTokensController::showHideGroup(const QString& groupId, bool flag) { if (flag) { // show const auto tokens = m_hiddenTokensModel->takeAllItems(groupId); - for (const auto& token: tokens) { - m_communityTokensModel->addItem(token); + if (!tokens.isEmpty()) { + for (const auto& token: tokens) { + m_communityTokensModel->addItem(token); + } + emit communityTokenGroupShown(tokens.constFirst().communityName); } m_communityIds.append(groupId); } else { // hide const auto tokens = m_communityTokensModel->takeAllItems(groupId); - for (const auto& token: tokens) { - m_hiddenTokensModel->addItem(token, false /*prepend*/); + if (!tokens.isEmpty()) { + for (const auto& token: tokens) { + m_hiddenTokensModel->addItem(token, false /*prepend*/); + } + emit communityTokenGroupHidden(tokens.constFirst().communityName); } m_communityIds.removeAll(groupId); } @@ -228,7 +239,7 @@ void ManageTokensController::settingsHideToken(const QString& symbol) m_settingsData.remove(symbol); // remove all m_settingsData.insert(symbol, {pos, false, group}); } else { - m_settingsData.insert(symbol, {0, false, QString()}); + m_settingsData.insert(symbol, {0, false, {}}); } saveSettings(true); diff --git a/ui/StatusQ/src/wallet/managetokenscontroller.h b/ui/StatusQ/src/wallet/managetokenscontroller.h index e5ace7d7ce..72a704bf11 100644 --- a/ui/StatusQ/src/wallet/managetokenscontroller.h +++ b/ui/StatusQ/src/wallet/managetokenscontroller.h @@ -16,7 +16,7 @@ class ManageTokensController : public QObject, public QQmlParserStatus // input properties Q_PROPERTY(QAbstractItemModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged FINAL) Q_PROPERTY(QString settingsKey READ settingsKey WRITE setSettingsKey NOTIFY settingsKeyChanged FINAL REQUIRED) - Q_PROPERTY(bool arrangeByCommunity READ arrangeByCommunity WRITE setArrangeByCommunity NOTIFY arrangeByCommunityChanged FINAL) // TODO persist in settings + Q_PROPERTY(bool arrangeByCommunity READ arrangeByCommunity WRITE setArrangeByCommunity NOTIFY arrangeByCommunityChanged FINAL) // TODO persist in settings? // TODO arrangeByCollection for collectibles // output properties @@ -58,6 +58,12 @@ signals: void settingsKeyChanged(); void settingsDirtyChanged(bool dirty); + void tokenHidden(const QString& symbol, const QString& name); + void tokenShown(const QString& symbol, const QString& name); + void communityTokenGroupHidden(const QString& communityName); + void communityTokenGroupShown(const QString& communityName); + // TODO collectionTokenGroupHidden(const QString& collectionName); + private: QAbstractItemModel* m_sourceModel{nullptr}; QAbstractItemModel* sourceModel() const { return m_sourceModel; } diff --git a/ui/StatusQ/src/wallet/managetokensmodel.cpp b/ui/StatusQ/src/wallet/managetokensmodel.cpp index 45b8922eb3..877e4b1c88 100644 --- a/ui/StatusQ/src/wallet/managetokensmodel.cpp +++ b/ui/StatusQ/src/wallet/managetokensmodel.cpp @@ -36,7 +36,6 @@ void ManageTokensModel::addItem(const TokenData& item, bool append) beginInsertRows({}, destRow, destRow); append ? m_data.append(item) : m_data.prepend(item); endInsertRows(); - setDirty(true); } std::optional ManageTokensModel::takeItem(int row) @@ -47,7 +46,6 @@ std::optional ManageTokensModel::takeItem(int row) beginRemoveRows({}, row, row); auto res = m_data.takeAt(row); endRemoveRows(); - setDirty(true); return res; } @@ -72,7 +70,6 @@ QList ManageTokensModel::takeAllItems(const QString& communityId) endRemoveRows(); } - setDirty(true); return result; } diff --git a/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml b/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml index cee4a22f8f..2c90038be6 100644 --- a/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml +++ b/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml @@ -94,9 +94,17 @@ DropArea { isCommunityAsset: !!model.communityId isCollectible: root.isCollectible onMoveRequested: (from, to) => root.ListView.view.model.moveItem(from, to) - onShowHideRequested: (index, flag) => isCommunityAsset ? root.controller.showHideCommunityToken(index, flag) - : root.controller.showHideRegularToken(index, flag) - onShowHideGroupRequested: (groupId, flag) => root.controller.showHideGroup(groupId, flag) + onShowHideRequested: function(index, flag) { + if (isCommunityAsset) + root.controller.showHideCommunityToken(index, flag) + else + root.controller.showHideRegularToken(index, flag) + root.controller.saveSettings() + } + onShowHideGroupRequested: function(groupId, flag) { + root.controller.showHideGroup(groupId, flag) + root.controller.saveSettings() + } } ] } diff --git a/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml b/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml index 5cf44f8fdd..ed801bf04d 100644 --- a/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml +++ b/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml @@ -116,7 +116,10 @@ DropArea { isCollectible: root.isCollectible groupId: model.communityId onMoveRequested: (from, to) => root.controller.communityTokenGroupsModel.moveItem(from, to) // TODO collection - onShowHideGroupRequested: (groupId, flag) => root.controller.showHideGroup(groupId, flag) + onShowHideGroupRequested: function(groupId, flag) { + root.controller.showHideGroup(groupId, flag) + root.controller.saveSettings() + } } } diff --git a/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml b/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml index b981fc8878..47965aa460 100644 --- a/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml @@ -44,6 +44,12 @@ Control { sourceModel: root.baseModel arrangeByCommunity: switchArrangeByCommunity.checked settingsKey: "WalletAssets" + onTokenHidden: (symbol, name) => Global.displayToastMessage( + qsTr("%1 (%2) was successfully hidden.").arg(name).arg(symbol), "", "checkmark-circle", + false, Constants.ephemeralNotificationType.success, "") + onCommunityTokenGroupHidden: (communityName) => Global.displayToastMessage( + qsTr("%1 community assets successfully hidden").arg(communityName), "", "checkmark-circle", + false, Constants.ephemeralNotificationType.success, "") } } diff --git a/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml b/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml index 24a4680214..ce8872904c 100644 --- a/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml @@ -58,6 +58,12 @@ Control { sourceModel: d.renamedModel arrangeByCommunity: switchArrangeByCommunity.checked settingsKey: "WalletCollectibles" + onTokenHidden: (symbol, name) => Global.displayToastMessage( + qsTr("%1 was successfully hidden.").arg(name), "", "checkmark-circle", + false, Constants.ephemeralNotificationType.success, "") + onCommunityTokenGroupHidden: (communityName) => Global.displayToastMessage( + qsTr("%1 community collectibles successfully hidden").arg(communityName), "", "checkmark-circle", + false, Constants.ephemeralNotificationType.success, "") } }