import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import Qt.labs.settings 1.1 import StatusQ 0.1 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Core.Utils 0.1 as SQUtils import StatusQ.Controls 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 import StatusQ.Popups.Dialog 0.1 import StatusQ.Models 0.1 import StatusQ.Internal 0.1 import SortFilterProxyModel 0.2 import utils 1.0 import shared.stores 1.0 import shared.controls 1.0 import shared.popups 1.0 import AppLayouts.Wallet.controls 1.0 ColumnLayout { id: root // expected roles: name, symbol, balances, currencyPrice, changePct24hour, communityId, communityName, communityImage required property var assets property var currencyStore property var networkConnectionStore property var overview property bool assetDetailsLaunched: false property bool filterVisible property bool areAssetsLoading: false property string addressFilters property string networkFilters signal assetClicked(var token) signal sendRequested(string symbol) signal receiveRequested(string symbol) signal switchToCommunityRequested(string communityId) signal manageTokensRequested() spacing: 0 QtObject { id: d property int selectedAssetIndex: -1 readonly property int loadingItemsCount: 25 readonly property bool isCustomView: cmbTokenOrder.currentValue === SortOrderComboBox.TokenOrderCustom function tokenIsVisible(symbol) { // NOTE Backend returns ETH, SNT, STT and DAI by default if (!d.controller.filterAcceptsSymbol(symbol)) // explicitely hidden return false // Received tokens can have 0 balance, which indicate previosuly owned token return true // TODO handle UI threshold (#12611) } readonly property var controller: ManageTokensController { settingsKey: "WalletAssets" } function hideAllCommunityTokens(communityId) { const tokenSymbols = ModelUtils.getAll(assetsListView.model, "symbol", "communityId", communityId) d.controller.settingsHideGroupTokens(communityId, tokenSymbols) } function getTotalBalance(balances, decimals) { let totalBalance = 0 let nwFilters = root.networkFilters.split(":") let addrFilters = root.addressFilters.split(":") for(let i=0; i { if (mouse.button === Qt.LeftButton) { RootStore.getHistoricalDataForToken(modelData.symbol, root.currencyStore.currentCurrency) d.selectedAssetIndex = delegateIndex assetClicked(assetsListView.model.get(delegateIndex)) } else if (mouse.button === Qt.RightButton) { Global.openMenu(tokenContextMenu, this, {symbol: modelData.symbol, assetName: modelData.name, assetImage: symbolUrl, communityId: modelData.communityId, communityName: modelData.communityName, communityImage: modelData.communityImage}) } } onSwitchToCommunityRequested: root.switchToCommunityRequested(communityId) Component.onCompleted: { // on Model reset if the detail view is shown, update the data in background. if(root.assetDetailsLaunched && delegateIndex === d.selectedAssetIndex) { assetClicked(assetsListView.model.get(delegateIndex)) } } } } Component { id: tokenContextMenu StatusMenu { onClosed: destroy() property string symbol property string assetName property string assetImage property string communityId property string communityName property string communityImage StatusAction { enabled: root.networkConnectionStore.sendBuyBridgeEnabled && !root.overview.isWatchOnlyAccount && root.overview.canSend icon.name: "send" text: qsTr("Send") onTriggered: root.sendRequested(symbol) } StatusAction { icon.name: "receive" text: qsTr("Receive") onTriggered: root.receiveRequested(symbol) } StatusMenuSeparator {} StatusAction { icon.name: "settings" text: qsTr("Manage tokens") onTriggered: root.manageTokensRequested() } StatusAction { enabled: symbol !== "ETH" type: StatusAction.Type.Danger icon.name: "hide" text: qsTr("Hide asset") onTriggered: Global.openPopup(confirmHideAssetPopup, {symbol, assetName, assetImage, communityId}) } StatusAction { enabled: !!communityId type: StatusAction.Type.Danger icon.name: "hide" text: qsTr("Hide all assets from this community") onTriggered: Global.openPopup(confirmHideCommunityAssetsPopup, {communityId, communityName, communityImage}) } } } Component { id: communityInfoPopupCmp StatusDialog { destroyOnClose: true title: qsTr("What are community assets?") standardButtons: Dialog.Ok width: 520 contentItem: StatusBaseText { wrapMode: Text.Wrap text: qsTr("Community assets are assets that have been minted by a community. As these assets cannot be verified, always double check their origin and validity before interacting with them. If in doubt, ask a trusted member or admin of the relevant community.") } } } Component { id: confirmHideAssetPopup ConfirmationDialog { property string symbol property string assetName property string assetImage property string communityId readonly property string formattedName: assetName + (communityId ? " (" + qsTr("community asset") + ")" : "") width: 520 destroyOnClose: true confirmButtonLabel: qsTr("Hide %1").arg(assetName) cancelBtnType: "" showCancelButton: true headerSettings.title: qsTr("Hide %1").arg(formattedName) headerSettings.asset.name: assetImage confirmationText: qsTr("Are you sure you want to hide %1? You will no longer see or be able to interact with this asset anywhere inside Status.").arg(formattedName) onCancelButtonClicked: close() onConfirmButtonClicked: { d.controller.settingsHideToken(symbol) close() Global.displayToastMessage( qsTr("%1 was successfully hidden. You can toggle asset visibility via %2.").arg(formattedName) .arg(`` + qsTr("Settings", "Go to Settings") + ""), "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "" ) } } } Component { id: confirmHideCommunityAssetsPopup ConfirmationDialog { property string communityId property string communityName property string communityImage width: 520 destroyOnClose: true confirmButtonLabel: qsTr("Hide all assets minted by this community") cancelBtnType: "" showCancelButton: true headerSettings.title: qsTr("Hide %1 community assets").arg(communityName) headerSettings.asset.name: communityImage confirmationText: qsTr("Are you sure you want to hide all community assets minted by %1? You will no longer see or be able to interact with these assets anywhere inside Status.").arg(communityName) onCancelButtonClicked: close() onConfirmButtonClicked: { d.hideAllCommunityTokens(communityId) close() Global.displayToastMessage( qsTr("%1 community assets were successfully hidden. You can toggle asset visibility via %2.").arg(communityName) .arg(`` + qsTr("Settings", "Go to Settings") + ""), "", "checkmark-circle", false, Constants.ephemeralNotificationType.success, "" ) } } } }