mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-10 06:16:32 +00:00
fa4755ce9e
+ store the card state in user settings + amend the BannerCard close button state. It needs to change color on hover and to become visible only when the card is hovered.
508 lines
24 KiB
QML
508 lines
24 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import Qt.labs.settings 1.1
|
|
|
|
import StatusQ.Components 0.1
|
|
import StatusQ.Controls 0.1
|
|
import StatusQ.Core 0.1
|
|
import StatusQ.Core.Theme 0.1
|
|
import StatusQ.Core.Utils 0.1
|
|
import StatusQ.Popups.Dialog 0.1
|
|
|
|
import AppLayouts.Wallet.controls 1.0
|
|
|
|
import utils 1.0
|
|
import shared.controls 1.0
|
|
import shared.views 1.0
|
|
import shared.stores 1.0 as SharedStores
|
|
import shared.panels 1.0
|
|
|
|
import "./"
|
|
import "../stores"
|
|
import "../panels"
|
|
import "../views/collectibles"
|
|
|
|
RightTabBaseView {
|
|
id: root
|
|
|
|
enum TabIndex {
|
|
Assets = 0,
|
|
Collectibles = 1,
|
|
Activity = 2
|
|
}
|
|
|
|
property SharedStores.RootStore sharedRootStore
|
|
|
|
property alias currentTabIndex: walletTabBar.currentIndex
|
|
|
|
signal launchShareAddressModal()
|
|
signal launchBuyCryptoModal()
|
|
signal launchSwapModal(string tokensKey)
|
|
|
|
function resetView() {
|
|
resetStack()
|
|
root.currentTabIndex = 0
|
|
}
|
|
|
|
function resetStack() {
|
|
stack.currentIndex = 0;
|
|
RootStore.backButtonName = d.getBackButtonText(stack.currentIndex);
|
|
}
|
|
|
|
headerButton.onClicked: {
|
|
root.launchShareAddressModal()
|
|
}
|
|
header.visible: stack.currentIndex === 0
|
|
|
|
StackLayout {
|
|
id: stack
|
|
anchors.fill: parent
|
|
|
|
onCurrentIndexChanged: {
|
|
RootStore.backButtonName = d.getBackButtonText(currentIndex)
|
|
}
|
|
|
|
QtObject {
|
|
id: d
|
|
function getBackButtonText(index) {
|
|
switch(index) {
|
|
case 1:
|
|
return qsTr("Collectibles")
|
|
case 2:
|
|
return qsTr("Assets")
|
|
case 3:
|
|
return qsTr("Activity")
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
readonly property var detailedCollectibleActivityController: RootStore.tmpActivityController0
|
|
}
|
|
|
|
Settings {
|
|
id: walletSettings
|
|
category: "walletSettings-" + root.contactsStore.myPublicKey
|
|
property real collectiblesViewCustomOrderApplyTimestamp: 0
|
|
property bool buyBannerEnabled: true
|
|
property bool receiveBannerEnabled: true
|
|
}
|
|
|
|
Component {
|
|
id: buyReceiveBannerComponent
|
|
BuyReceiveBanner {
|
|
id: banner
|
|
topPadding: anyVisibleItems ? 8 : 0
|
|
bottomPadding: anyVisibleItems ? 20 : 0
|
|
|
|
onBuyClicked: root.launchBuyCryptoModal()
|
|
onReceiveClicked: root.launchShareAddressModal()
|
|
buyEnabled: walletSettings.buyBannerEnabled
|
|
receiveEnabled: walletSettings.receiveBannerEnabled
|
|
onCloseBuy: walletSettings.buyBannerEnabled = false
|
|
onCloseReceive: walletSettings.receiveBannerEnabled = false
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: confirmHideCommunityAssetsPopup
|
|
|
|
ConfirmHideCommunityAssetsPopup {
|
|
destroyOnClose: true
|
|
|
|
required property string communityId
|
|
|
|
onConfirmButtonClicked: {
|
|
RootStore.walletAssetsStore.assetsController.showHideGroup(communityId, false /*hide*/)
|
|
close();
|
|
}
|
|
}
|
|
}
|
|
|
|
// StackLayout.currentIndex === 0
|
|
ColumnLayout {
|
|
spacing: 0
|
|
|
|
ImportKeypairInfo {
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Theme.bigPadding
|
|
Layout.preferredHeight: childrenRect.height
|
|
visible: root.store.walletSectionInst.hasPairedDevices && root.store.walletSectionInst.keypairOperabilityForObservedAccount === Constants.keypair.operability.nonOperable
|
|
|
|
onRunImport: {
|
|
root.store.walletSectionInst.runKeypairImportPopup()
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
StatusTabBar {
|
|
id: walletTabBar
|
|
objectName: "rightSideWalletTabBar"
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Theme.padding
|
|
|
|
StatusTabButton {
|
|
objectName: "assetsTabButton"
|
|
leftPadding: 0
|
|
width: implicitWidth
|
|
text: qsTr("Assets")
|
|
}
|
|
StatusTabButton {
|
|
objectName: "collectiblesTabButton"
|
|
width: implicitWidth
|
|
text: qsTr("Collectibles")
|
|
}
|
|
StatusTabButton {
|
|
objectName: "activityTabButton"
|
|
rightPadding: 0
|
|
width: implicitWidth
|
|
text: qsTr("Activity")
|
|
|
|
StatusBetaTag {
|
|
// TODO remove me when Activity is no longer experimental
|
|
// Keep Activity as the last tab for now as the Experimental tag don't flow
|
|
anchors.top: parent.top
|
|
anchors.topMargin: 6
|
|
anchors.left: parent.right
|
|
anchors.leftMargin: 5
|
|
cursorShape: Qt.PointingHandCursor
|
|
}
|
|
}
|
|
onCurrentIndexChanged: {
|
|
RootStore.setCurrentViewedHoldingType(walletTabBar.currentIndex === 1 ? Constants.TokenType.ERC721 : Constants.TokenType.ERC20)
|
|
}
|
|
}
|
|
StatusFlatButton {
|
|
id: filterButton
|
|
objectName: "filterButton"
|
|
icon.name: "filter"
|
|
checkable: true
|
|
icon.color: checked ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
|
Behavior on icon.color { ColorAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
|
highlighted: checked
|
|
visible: walletTabBar.currentIndex !== RightTabView.TabIndex.Activity // TODO #16761: Re-enable filter for activity when implemented
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
id: mainViewLoader
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
sourceComponent: {
|
|
switch (walletTabBar.currentIndex) {
|
|
case RightTabView.TabIndex.Assets: return assetsView
|
|
case RightTabView.TabIndex.Collectibles: return collectiblesView
|
|
case RightTabView.TabIndex.Activity: return historyView
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: assetsView
|
|
|
|
AssetsView {
|
|
AssetsViewAdaptor {
|
|
id: assetsViewAdaptor
|
|
|
|
accounts: RootStore.addressFilters
|
|
chains: RootStore.networkFiltersArray
|
|
|
|
marketValueThreshold:
|
|
RootStore.tokensStore.displayAssetsBelowBalance
|
|
? RootStore.tokensStore.getDisplayAssetsBelowBalanceThresholdDisplayAmount()
|
|
: 0
|
|
|
|
Connections {
|
|
target: RootStore.tokensStore
|
|
|
|
function displayAssetsBelowBalanceThresholdChanged() {
|
|
assetsViewAdaptor.marketValueThresholdChanged()
|
|
}
|
|
}
|
|
|
|
tokensModel: RootStore.walletAssetsStore.groupedAccountAssetsModel
|
|
|
|
formatBalance: (balance, symbol) => {
|
|
return LocaleUtils.currencyAmountToLocaleString(
|
|
RootStore.currencyStore.getCurrencyAmount(balance, symbol))
|
|
}
|
|
|
|
chainsError: (chains) => {
|
|
if (!root.networkConnectionStore)
|
|
return ""
|
|
return root.networkConnectionStore.getBlockchainNetworkDownText(chains)
|
|
}
|
|
}
|
|
|
|
function refreshSortSettings() {
|
|
settings.category = settingsCategoryName
|
|
walletSettings.sync()
|
|
settings.sync()
|
|
let value = SortOrderComboBox.TokenOrderBalance
|
|
if (walletSettings.assetsViewCustomOrderApplyTimestamp > settings.sortOrderUpdateTimestamp && customOrderAvailable) {
|
|
value = SortOrderComboBox.TokenOrderCustom
|
|
} else {
|
|
value = settings.currentSortValue
|
|
}
|
|
sortByValue(value)
|
|
setSortOrder(settings.currentSortOrder)
|
|
}
|
|
|
|
function saveSortSettings() {
|
|
settings.currentSortValue = getSortValue()
|
|
settings.currentSortOrder = getSortOrder()
|
|
settings.sortOrderUpdateTimestamp = new Date().getTime()
|
|
settings.sync()
|
|
}
|
|
|
|
readonly property string settingsCategoryName: {
|
|
const addressFilters = RootStore.addressFilters
|
|
return "AssetsViewSortSettings-" + (addressFilters.indexOf(':') > -1 ? "all" : addressFilters)
|
|
}
|
|
onSettingsCategoryNameChanged: {
|
|
saveSortSettings()
|
|
refreshSortSettings()
|
|
}
|
|
|
|
Component.onCompleted: refreshSortSettings()
|
|
Component.onDestruction: saveSortSettings()
|
|
|
|
readonly property Settings walletSettings: Settings {
|
|
id: walletSettings
|
|
category: "walletSettings-" + root.contactsStore.myPublicKey
|
|
property var assetsViewCustomOrderApplyTimestamp
|
|
}
|
|
|
|
readonly property Settings settings: Settings {
|
|
id: settings
|
|
property int currentSortValue: SortOrderComboBox.TokenOrderDateAdded
|
|
property var sortOrderUpdateTimestamp
|
|
property int currentSortOrder: Qt.DescendingOrder
|
|
}
|
|
|
|
loading: RootStore.overview.balanceLoading
|
|
sorterVisible: filterButton.checked
|
|
customOrderAvailable: RootStore.walletAssetsStore.assetsController.hasSettings
|
|
model: assetsViewAdaptor.model
|
|
bannerComponent: buyReceiveBannerComponent
|
|
|
|
marketDataError: !!root.networkConnectionStore
|
|
? root.networkConnectionStore.getMarketNetworkDownText()
|
|
: ""
|
|
balanceError: {
|
|
if (!root.networkConnectionStore)
|
|
return ""
|
|
|
|
return (root.networkConnectionStore.noBlockchainConnectionAndNoCache
|
|
&& !root.networkConnectionStore.noMarketConnectionAndNoCache)
|
|
? root.networkConnectionStore.noBlockchainConnectionAndNoCacheText
|
|
: ""
|
|
}
|
|
|
|
formatFiat: balance => RootStore.currencyStore.formatCurrencyAmount(
|
|
balance, RootStore.currencyStore.currentCurrency)
|
|
|
|
sendEnabled: root.networkConnectionStore.sendBuyBridgeEnabled &&
|
|
!RootStore.overview.isWatchOnlyAccount && RootStore.overview.canSend
|
|
communitySendEnabled: RootStore.tokensStore.showCommunityAssetsInSend
|
|
swapEnabled: !RootStore.overview.isWatchOnlyAccount
|
|
swapVisible: root.swapEnabled
|
|
|
|
onSendRequested: {
|
|
const modal = root.sendModal
|
|
|
|
modal.preSelectedSendType = Constants.SendType.Transfer
|
|
modal.preSelectedHoldingID = key
|
|
modal.preSelectedHoldingType = Constants.TokenType.ERC20
|
|
modal.onlyAssets = true
|
|
modal.open()
|
|
}
|
|
|
|
onSwapRequested: root.launchSwapModal(key)
|
|
onReceiveRequested: root.launchShareAddressModal()
|
|
onCommunityClicked: Global.switchToCommunity(communityKey)
|
|
|
|
onHideRequested: (key) => {
|
|
const token = ModelUtils.getByKey(model, "key", key)
|
|
Global.openConfirmHideAssetPopup(token.symbol, token.name, token.icon, !!token.communityId)
|
|
}
|
|
onHideCommunityAssetsRequested:
|
|
(communityKey) => {
|
|
const community = ModelUtils.getByKey(model, "communityId", communityKey)
|
|
confirmHideCommunityAssetsPopup.createObject(root, {
|
|
name: community.communityName,
|
|
icon: community.communityIcon,
|
|
communityId: communityKey }
|
|
).open()
|
|
}
|
|
onManageTokensRequested: Global.changeAppSectionBySectionType(
|
|
Constants.appSection.profile,
|
|
Constants.settingsSubsection.wallet,
|
|
Constants.walletSettingsSubsection.manageAssets)
|
|
onAssetClicked: (key) => {
|
|
const token = ModelUtils.getByKey(model, "key", key)
|
|
|
|
RootStore.tokensStore.getHistoricalDataForToken(
|
|
token.symbol, RootStore.currencyStore.currentCurrency)
|
|
|
|
assetDetailView.token = token
|
|
RootStore.setCurrentViewedHolding(
|
|
token.symbol, token.key, Constants.TokenType.ERC20, token.communityId ?? "")
|
|
stack.currentIndex = 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: collectiblesView
|
|
CollectiblesView {
|
|
id: collView
|
|
function refreshSortSettings() {
|
|
settings.category = settingsCategoryName
|
|
walletSettings.sync()
|
|
settings.sync()
|
|
let value = SortOrderComboBox.TokenOrderBalance
|
|
if (walletSettings.collectiblesViewCustomOrderApplyTimestamp > settings.sortOrderUpdateTimestamp && customOrderAvailable) {
|
|
value = SortOrderComboBox.TokenOrderCustom
|
|
} else {
|
|
value = settings.currentSortValue
|
|
}
|
|
sortByValue(value)
|
|
setSortOrder(settings.currentSortOrder)
|
|
}
|
|
|
|
function saveSortSettings() {
|
|
settings.currentSortValue = getSortValue()
|
|
settings.currentSortOrder = getSortOrder()
|
|
settings.sortOrderUpdateTimestamp = new Date().getTime()
|
|
settings.sync()
|
|
}
|
|
|
|
readonly property string settingsCategoryName: "CollectiblesViewSortSettings-" + (addressFilters.indexOf(':') > -1 ? "all" : addressFilters)
|
|
onSettingsCategoryNameChanged: {
|
|
saveSortSettings()
|
|
refreshSortSettings()
|
|
}
|
|
|
|
Component.onCompleted: refreshSortSettings()
|
|
Component.onDestruction: saveSortSettings()
|
|
|
|
readonly property Settings settings: Settings {
|
|
id: settings
|
|
property int currentSortValue: SortOrderComboBox.TokenOrderDateAdded
|
|
property real sortOrderUpdateTimestamp: 0
|
|
property alias selectedFilterGroupIds: collView.selectedFilterGroupIds
|
|
property int currentSortOrder: Qt.DescendingOrder
|
|
}
|
|
|
|
ownedAccountsModel: RootStore.nonWatchAccounts
|
|
controller: RootStore.collectiblesStore.collectiblesController
|
|
networkFilters: RootStore.networkFilters
|
|
addressFilters: RootStore.addressFilters
|
|
sendEnabled: root.networkConnectionStore.sendBuyBridgeEnabled && !RootStore.overview.isWatchOnlyAccount && RootStore.overview.canSend
|
|
filterVisible: filterButton.checked
|
|
customOrderAvailable: controller.hasSettings
|
|
bannerComponent: buyReceiveBannerComponent
|
|
onCollectibleClicked: {
|
|
RootStore.collectiblesStore.getDetailedCollectible(chainId, contractAddress, tokenId)
|
|
RootStore.setCurrentViewedHolding(uid, uid, tokenType, communityId)
|
|
d.detailedCollectibleActivityController.resetFilter()
|
|
d.detailedCollectibleActivityController.setFilterAddressesJson(JSON.stringify(RootStore.addressFilters.split(":")))
|
|
d.detailedCollectibleActivityController.setFilterChainsJson(JSON.stringify([chainId]), false)
|
|
d.detailedCollectibleActivityController.setFilterCollectibles(JSON.stringify([uid]))
|
|
d.detailedCollectibleActivityController.updateFilter()
|
|
|
|
stack.currentIndex = 1
|
|
}
|
|
onSendRequested: (symbol, tokenType, fromAddress) => {
|
|
const collectible = ModelUtils.getByKey(controller.sourceModel, "symbol", symbol)
|
|
if (!!collectible && collectible.communityPrivilegesLevel === Constants.TokenPrivilegesLevel.Owner) {
|
|
Global.openTransferOwnershipPopup(collectible.communityId,
|
|
collectible.communityName,
|
|
collectible.communityImage,
|
|
{
|
|
key: collectible.tokenId,
|
|
privilegesLevel: collectible.communityPrivilegesLevel,
|
|
chainId: collectible.chainId,
|
|
name: collectible.name,
|
|
artworkSource: collectible.communityImage,
|
|
accountAddress: fromAddress,
|
|
tokenAddress: collectible.contractAddress
|
|
},
|
|
root.sendModal)
|
|
return
|
|
}
|
|
|
|
root.sendModal.preSelectedAccountAddress = fromAddress
|
|
root.sendModal.preSelectedHoldingID = symbol
|
|
root.sendModal.preSelectedHoldingType = tokenType
|
|
root.sendModal.preSelectedSendType = tokenType === Constants.TokenType.ERC721 ?
|
|
Constants.SendType.ERC721Transfer:
|
|
Constants.SendType.ERC1155Transfer
|
|
root.sendModal.onlyAssets = false
|
|
root.sendModal.open()
|
|
}
|
|
onReceiveRequested: (symbol) => root.launchShareAddressModal()
|
|
onSwitchToCommunityRequested: (communityId) => Global.switchToCommunity(communityId)
|
|
onManageTokensRequested: Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.wallet,
|
|
Constants.walletSettingsSubsection.manageCollectibles)
|
|
isFetching: RootStore.collectiblesStore.areCollectiblesFetching
|
|
isUpdating: RootStore.collectiblesStore.areCollectiblesUpdating
|
|
isError: RootStore.collectiblesStore.areCollectiblesError
|
|
}
|
|
}
|
|
Component {
|
|
id: historyView
|
|
HistoryView {
|
|
overview: RootStore.overview
|
|
walletRootStore: RootStore
|
|
communitiesStore: root.communitiesStore
|
|
currencyStore: root.sharedRootStore.currencyStore
|
|
showAllAccounts: RootStore.showAllAccounts
|
|
filterVisible: false // TODO #16761: Re-enable filter for activity when implemented
|
|
bannerComponent: buyReceiveBannerComponent
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CollectibleDetailView {
|
|
id: collectibleDetailView
|
|
|
|
visible : (stack.currentIndex === 1)
|
|
|
|
collectible: RootStore.collectiblesStore.detailedCollectible
|
|
isCollectibleLoading: RootStore.collectiblesStore.isDetailedCollectibleLoading
|
|
activityModel: d.detailedCollectibleActivityController.model
|
|
addressFilters: RootStore.addressFilters
|
|
rootStore: root.sharedRootStore
|
|
walletRootStore: RootStore
|
|
communitiesStore: root.communitiesStore
|
|
|
|
onVisibleChanged: {
|
|
if (!visible) {
|
|
RootStore.resetCurrentViewedHolding(Constants.TokenType.ERC721)
|
|
RootStore.collectiblesStore.resetDetailedCollectible()
|
|
}
|
|
}
|
|
}
|
|
AssetsDetailView {
|
|
id: assetDetailView
|
|
|
|
visible: (stack.currentIndex === 2)
|
|
|
|
tokensStore: RootStore.tokensStore
|
|
allNetworksModel: RootStore.filteredFlatModel
|
|
address: RootStore.overview.mixedcaseAddress
|
|
currencyStore: RootStore.currencyStore
|
|
networkFilters: RootStore.networkFilters
|
|
|
|
networkConnectionStore: root.networkConnectionStore
|
|
|
|
onVisibleChanged: {
|
|
if (!visible)
|
|
RootStore.resetCurrentViewedHolding(Constants.TokenType.ERC20)
|
|
}
|
|
}
|
|
}
|
|
}
|