diff --git a/storybook/pages/ManageAssetsPanelPage.qml b/storybook/pages/ManageAssetsPanelPage.qml index c3c73b1e04..f3bd389b8d 100644 --- a/storybook/pages/ManageAssetsPanelPage.qml +++ b/storybook/pages/ManageAssetsPanelPage.qml @@ -24,33 +24,32 @@ SplitView { assetsWithFilteredBalances: groupedAccountsAssetsModel } - StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml + ManageAssetsPanel { + id: showcasePanel + SplitView.fillWidth: true SplitView.fillHeight: true - Component.onCompleted: forceActiveFocus() - ManageAssetsPanel { - id: showcasePanel - width: 500 - getCurrencyAmount: function (balance, symbol) { - return ({ - amount: balance, - symbol: symbol, - displayDecimals: 2, - stripTrailingZeroes: false - }) - } - getCurrentCurrencyAmount: function (balance) { - return ({ - amount: balance, - symbol: "USD", - displayDecimals: 2, - stripTrailingZeroes: false - }) - } - controller: ManageTokensController { - sourceModel: ctrlEmptyModel.checked ? null : walletAssetStore.groupedAccountAssetsModel - settingsKey: "WalletAssets" - } + + getCurrencyAmount: function (balance, symbol) { + return ({ + amount: balance, + symbol: symbol, + displayDecimals: 2, + stripTrailingZeroes: false + }) + } + getCurrentCurrencyAmount: function (balance) { + return ({ + amount: balance, + symbol: "USD", + displayDecimals: 2, + stripTrailingZeroes: false + }) + } + + controller: ManageTokensController { + sourceModel: ctrlEmptyModel.checked ? null : walletAssetStore.groupedAccountAssetsModel + settingsKey: "WalletAssets" } } diff --git a/storybook/pages/ManageCollectiblesPanelPage.qml b/storybook/pages/ManageCollectiblesPanelPage.qml index c67c7260fd..f078dfbae0 100644 --- a/storybook/pages/ManageCollectiblesPanelPage.qml +++ b/storybook/pages/ManageCollectiblesPanelPage.qml @@ -35,17 +35,15 @@ SplitView { ] } - StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml + ManageCollectiblesPanel { + id: showcasePanel + SplitView.fillWidth: true SplitView.fillHeight: true - Component.onCompleted: forceActiveFocus() - ManageCollectiblesPanel { - id: showcasePanel - width: 500 - controller: ManageTokensController { - sourceModel: renamedModel - settingsKey: "WalletCollectibles" - } + + controller: ManageTokensController { + sourceModel: renamedModel + settingsKey: "WalletCollectibles" } } @@ -94,7 +92,4 @@ SplitView { } // category: Panels -// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=19341-250476&mode=design&t=jR53lJ7aDzVHE4hZ-0 -// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=19655-204534&mode=design&t=jR53lJ7aDzVHE4hZ-0 -// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=19622-173583&mode=design&t=jR53lJ7aDzVHE4hZ-0 -// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=19622-179146&mode=design&t=jR53lJ7aDzVHE4hZ-0 +// https://www.figma.com/file/eM26pyHZUeAwMLviaS1KJn/%E2%9A%99%EF%B8%8F-Wallet-Settings%3A-Manage-Tokens diff --git a/storybook/pages/ManageHiddenPanelPage.qml b/storybook/pages/ManageHiddenPanelPage.qml index 9fa00de559..cbd8fe1d31 100644 --- a/storybook/pages/ManageHiddenPanelPage.qml +++ b/storybook/pages/ManageHiddenPanelPage.qml @@ -52,33 +52,30 @@ SplitView { settingsKey: "WalletCollectibles" } - StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml + ManageHiddenPanel { + id: showcasePanel + SplitView.fillWidth: true SplitView.fillHeight: true - Component.onCompleted: forceActiveFocus() - ManageHiddenPanel { - id: showcasePanel - width: 500 - assetsController: assetsController - collectiblesController: collectiblesController + assetsController: assetsController + collectiblesController: collectiblesController - getCurrencyAmount: function (balance, symbol) { - return ({ - amount: balance, - symbol: symbol, - displayDecimals: 2, - stripTrailingZeroes: false - }) - } - getCurrentCurrencyAmount: function (balance) { - return ({ - amount: balance, - symbol: "USD", - displayDecimals: 2, - stripTrailingZeroes: false - }) - } + getCurrencyAmount: function (balance, symbol) { + return ({ + amount: balance, + symbol: symbol, + displayDecimals: 2, + stripTrailingZeroes: false + }) + } + getCurrentCurrencyAmount: function (balance) { + return ({ + amount: balance, + symbol: "USD", + displayDecimals: 2, + stripTrailingZeroes: false + }) } } diff --git a/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml b/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml index 92a3539135..f6a31cdef6 100644 --- a/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml +++ b/storybook/qmlTests/tests/tst_ManageCollectiblesPanel.qml @@ -12,7 +12,7 @@ import utils 1.0 Item { id: root width: 600 - height: 400 + height: 2000 ManageCollectiblesModel { id: collectiblesModel @@ -33,6 +33,7 @@ Item { id: componentUnderTest ManageCollectiblesPanel { width: 500 + height: contentItem.contentHeight controller: ManageTokensController { sourceModel: renamedModel settingsKey: "WalletCollectibles" @@ -59,7 +60,7 @@ Item { property ManageCollectiblesPanel controlUnderTest: null function findDelegateIndexWithTitle(listview, title) { - waitForItemPolished(listview) + waitForRendering(listview) const count = listview.count for (let i = 0; i < count; i++) { const item = listview.itemAtIndex(i) @@ -74,9 +75,12 @@ Item { verify(!!token) const delegateBtn = findChild(token, "btnManageTokenMenu-%1".arg(index)) verify(!!delegateBtn) + + waitForItemPolished(delegateBtn) mouseClick(delegateBtn) const btnMenuLoader = findChild(delegateBtn, "manageTokensContextMenuLoader") verify(!!btnMenuLoader) + tryCompare(btnMenuLoader, "active", true) const btnMenu = btnMenuLoader.item verify(!!btnMenu) @@ -92,105 +96,120 @@ Item { function init() { controlUnderTest = createTemporaryObject(componentUnderTest, root) - controlUnderTest.clearSettings() notificationSpy.clear() } + function cleanup() { + controlUnderTest.clearSettings() + } + function test_showHideSingleToken() { + waitForItemPolished(controlUnderTest) verify(!controlUnderTest.dirty) - const lvRegular = findChild(controlUnderTest, "lvRegularTokens") - verify(!!lvRegular) - const lvRegularCount = lvRegular.count - verify(lvRegularCount === 7) + const lvOther = findChild(controlUnderTest, "otherTokensListView") + verify(!!lvOther) - const delegate0 = findChild(lvRegular, "manageTokensDelegate-0") + tryCompare(lvOther, "count", 7) + const delegate0 = findChild(lvOther, "manageTokensDelegate-0") verify(!!delegate0) const title = delegate0.title tryCompare(notificationSpy, "count", 0) - triggerDelegateMenuAction(lvRegular, 0, "miHideCollectionToken") + triggerDelegateMenuAction(lvOther, 0, "miHideCollectionToken") // verify the signal to show the notification toast got fired tryCompare(notificationSpy, "count", 1) // verify we now have -1 regular tokens after the "hide" operation - tryCompare(lvRegular, "count", lvRegularCount-1) + tryCompare(lvOther, "count", 6) } function test_showHideCommunityGroup() { verify(!controlUnderTest.dirty) - const loaderCommunityTokens = findChild(controlUnderTest, "loaderCommunityTokens") - verify(!!loaderCommunityTokens) - tryCompare(loaderCommunityTokens, "active", true) - const switchArrangeByCommunity = findChild(controlUnderTest, "switchArrangeByCommunity") + const communityHeader = findChild(controlUnderTest, "communityHeader") + verify(!!communityHeader) + const switchArrangeByCommunity = findChild(communityHeader, "switch") verify(!!switchArrangeByCommunity) - switchArrangeByCommunity.toggle() - const lvCommunityTokenGroups = findChild(loaderCommunityTokens, "lvCommunityTokenGroups") - verify(!!lvCommunityTokenGroups) + + waitForRendering(switchArrangeByCommunity) + mouseClick(switchArrangeByCommunity) + tryCompare(switchArrangeByCommunity, "checked", true) + + tryCompare(controlUnderTest.controller, "arrangeByCommunity", true) + + waitForRendering(controlUnderTest) + const lvCommunity = findChild(controlUnderTest, "communityTokensListView") + verify(!!lvCommunity) // verify we have 2 community collectible groups - tryCompare(lvCommunityTokenGroups, "count", 3) + tryCompare(lvCommunity, "count", 3) tryCompare(notificationSpy, "count", 0) - triggerDelegateMenuAction(lvCommunityTokenGroups, 0, "miHideTokenGroup", true) + triggerDelegateMenuAction(lvCommunity, 0, "miHideTokenGroup", true) // verify the signal to show the notification toast got fired tryCompare(notificationSpy, "count", 1) // verify we have one less group - waitForItemPolished(lvCommunityTokenGroups) - tryCompare(lvCommunityTokenGroups, "count", 2) + waitForItemPolished(lvCommunity) + tryCompare(lvCommunity, "count", 2) } function test_dnd() { verify(!controlUnderTest.dirty) - const lvRegular = findChild(controlUnderTest, "lvRegularTokens") - verify(!!lvRegular) - verify(lvRegular.count !== 0) + const lvOther = findChild(controlUnderTest, "otherTokensListView") + verify(!!lvOther) + verify(lvOther.count !== 0) - const delegate0 = findChild(lvRegular, "manageTokensDelegate-0") + const delegate0 = findChild(lvOther, "manageTokensDelegate-0") verify(!!delegate0) const title0 = delegate0.title verify(!!title0) - const title1 = findChild(lvRegular, "manageTokensDelegate-1").title + const delegate1 = findChild(lvOther, "manageTokensDelegate-1") + const title1 = delegate1.title verify(!!title1) - // DND one item down (~80px in height) - mouseDrag(delegate0, delegate0.width/2, delegate0.height/2, 0, 80) + waitForRendering(delegate1) + + // DND one item up + mouseDrag(delegate1, delegate1.width/2, delegate1.height/2, 0, -delegate1.height) // cross compare the titles - tryCompare(findChild(lvRegular, "manageTokensDelegate-0"), "title", title1) - tryCompare(findChild(lvRegular, "manageTokensDelegate-1"), "title", title0) + tryCompare(findChild(lvOther, "manageTokensDelegate-0"), "title", title1) + tryCompare(findChild(lvOther, "manageTokensDelegate-1"), "title", title0) verify(controlUnderTest.dirty) } function test_group_dnd() { verify(!controlUnderTest.dirty) - const switchArrangeByCommunity = findChild(controlUnderTest, "switchArrangeByCommunity") + const communityHeader = findChild(controlUnderTest, "communityHeader") + verify(!!communityHeader) + const switchArrangeByCommunity = findChild(communityHeader, "switch") verify(!!switchArrangeByCommunity) + + waitForItemPolished(switchArrangeByCommunity) mouseClick(switchArrangeByCommunity) - const loaderCommunityTokens = findChild(controlUnderTest, "loaderCommunityTokens") - verify(!!loaderCommunityTokens) - tryCompare(loaderCommunityTokens, "active", true) - const lvCommunityTokenGroups = findChild(loaderCommunityTokens, "lvCommunityTokenGroups") - verify(!!lvCommunityTokenGroups) - waitForItemPolished(lvCommunityTokenGroups) - tryCompare(lvCommunityTokenGroups, "count", 3) + const lvCommunity = findChild(controlUnderTest, "communityTokensListView") + verify(!!lvCommunity) + waitForItemPolished(lvCommunity) + tryCompare(lvCommunity, "count", 3) - const group0 = findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-0") + const group0 = findChild(lvCommunity, "manageTokensGroupDelegate-0") const title0 = group0.title verify(!!title0) - const title1 = findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-1").title + const group1 = findChild(lvCommunity, "manageTokensGroupDelegate-1") + const title1 = group1.title verify(!!title1) verify(title0 !== title1) - // DND one group down (~80px in height) - mouseDrag(group0, group0.width/2, group0.height/2, 0, 80) + waitForRendering(group1) + + mouseDrag(group1, group1.width/2, group1.height/2, 0, -group1.height) // cross compare the titles - tryCompare(findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-0"), "title", title1) - tryCompare(findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-1"), "title", title0) + tryCompare(findChild(lvCommunity, "manageTokensGroupDelegate-0"), "title", title1) + tryCompare(findChild(lvCommunity, "manageTokensGroupDelegate-1"), "title", title0) verify(controlUnderTest.dirty) } @@ -199,101 +218,101 @@ Item { verify(!controlUnderTest.dirty) const titleToTest = "Bearz" - const switchArrangeByCommunity = findChild(controlUnderTest, "switchArrangeByCommunity") + const communityHeader = findChild(controlUnderTest, "communityHeader") + verify(!!communityHeader) + const switchArrangeByCommunity = findChild(communityHeader, "switch") verify(!!switchArrangeByCommunity) + waitForRendering(switchArrangeByCommunity) mouseClick(switchArrangeByCommunity) - const loaderCommunityTokens = findChild(controlUnderTest, "loaderCommunityTokens") - verify(!!loaderCommunityTokens) - tryCompare(loaderCommunityTokens, "active", true) - const lvCommunityTokenGroups = findChild(loaderCommunityTokens, "lvCommunityTokenGroups") - verify(!!lvCommunityTokenGroups) - waitForItemPolished(lvCommunityTokenGroups) - tryCompare(lvCommunityTokenGroups, "count", 3) + const lvCommunity = findChild(controlUnderTest, "communityTokensListView") + verify(!!lvCommunity) + waitForItemPolished(lvCommunity) + tryCompare(lvCommunity, "count", 3) // get the "Bearz" group at index 1 - var bearzGroupTokenDelegate = findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-1") + var bearzGroupTokenDelegate = findChild(lvCommunity, "manageTokensGroupDelegate-1") const bearzTitle = bearzGroupTokenDelegate.title compare(bearzTitle, titleToTest) verify(!!bearzGroupTokenDelegate) waitForItemPolished(bearzGroupTokenDelegate) // now move the Bearz group up so that it's first (ends up at index 0) - waitForItemPolished(lvCommunityTokenGroups) - triggerDelegateMenuAction(lvCommunityTokenGroups, 1, "miMoveUp", true) + waitForItemPolished(lvCommunity) + triggerDelegateMenuAction(lvCommunity, 1, "miMoveUp", true) verify(controlUnderTest.dirty) - bearzGroupTokenDelegate = findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-0") + bearzGroupTokenDelegate = findChild(lvCommunity, "manageTokensGroupDelegate-0") verify(!!bearzGroupTokenDelegate) // finally verify that the Bearz group is still at top - waitForItemPolished(lvCommunityTokenGroups) - tryCompare(findChild(lvCommunityTokenGroups, "manageTokensGroupDelegate-0"), "title", titleToTest) + waitForItemPolished(lvCommunity) + tryCompare(findChild(lvCommunity, "manageTokensGroupDelegate-0"), "title", titleToTest) } function test_moveOperations() { verify(!controlUnderTest.dirty) - const lvRegular = findChild(controlUnderTest, "lvRegularTokens") - verify(!!lvRegular) - verify(lvRegular.count !== 0) + const lvOther = findChild(controlUnderTest, "otherTokensListView") + verify(!!lvOther) + verify(lvOther.count !== 0) - var delegate0 = findChild(lvRegular, "manageTokensDelegate-0") + var delegate0 = findChild(lvOther, "manageTokensDelegate-0") verify(!!delegate0) const title = delegate0.title // verify moveUp and moveToTop is not available for the first item - const moveUpAction = findDelegateMenuAction(lvRegular, 0, "miMoveUp") + const moveUpAction = findDelegateMenuAction(lvOther, 0, "miMoveUp") tryCompare(moveUpAction, "enabled", false) - const moveTopAction = findDelegateMenuAction(lvRegular, 0, "miMoveToTop") + const moveTopAction = findDelegateMenuAction(lvOther, 0, "miMoveToTop") tryCompare(moveTopAction, "enabled", false) // trigger move to bottom - triggerDelegateMenuAction(lvRegular, 0, "miMoveToBottom") - waitForItemPolished(lvRegular) + waitForItemPolished(lvOther) + triggerDelegateMenuAction(lvOther, 0, "miMoveToBottom") verify(controlUnderTest.dirty) // verify the previous first and current last are actually the same item - const delegateN = findChild(lvRegular, "manageTokensDelegate-%1".arg(lvRegular.count-1)) + const delegateN = findChild(lvOther, "manageTokensDelegate-%1".arg(lvOther.count-1)) verify(!!delegateN) const titleN = delegateN.title compare(title, titleN) // verify move down and to bottom is not available for the last item - const moveDownAction = findDelegateMenuAction(lvRegular, lvRegular.count-1, "miMoveDown") + const moveDownAction = findDelegateMenuAction(lvOther, lvOther.count-1, "miMoveDown") tryCompare(moveDownAction, "enabled", false) - const moveBottomAction = findDelegateMenuAction(lvRegular, lvRegular.count-1, "miMoveToBottom") + const moveBottomAction = findDelegateMenuAction(lvOther, lvOther.count-1, "miMoveToBottom") tryCompare(moveBottomAction, "enabled", false) // trigger move to top and verify we got the same title (item) again - triggerDelegateMenuAction(lvRegular, lvRegular.count-1, "miMoveToTop") - waitForItemPolished(lvRegular) - tryCompare(findChild(lvRegular, "manageTokensDelegate-0"), "title", title) + triggerDelegateMenuAction(lvOther, lvOther.count-1, "miMoveToTop") + waitForItemPolished(lvOther) + tryCompare(findChild(lvOther, "manageTokensDelegate-0"), "title", title) // trigger move down and verify we got the same title (item) again - triggerDelegateMenuAction(lvRegular, 0, "miMoveDown") - tryCompare(findChild(lvRegular, "manageTokensDelegate-1"), "title", title) + triggerDelegateMenuAction(lvOther, 0, "miMoveDown") + tryCompare(findChild(lvOther, "manageTokensDelegate-1"), "title", title) // trigger move up and verify we got the same title (item) again - triggerDelegateMenuAction(lvRegular, 1, "miMoveUp") - tryCompare(findChild(lvRegular, "manageTokensDelegate-0"), "title", title) + triggerDelegateMenuAction(lvOther, 1, "miMoveUp") + tryCompare(findChild(lvOther, "manageTokensDelegate-0"), "title", title) } function test_saveLoad() { verify(!controlUnderTest.dirty) const titleToTest = "Big Kitty" - let lvRegular = findChild(controlUnderTest, "lvRegularTokens") - verify(!!lvRegular) - const bigKittyIndex = findDelegateIndexWithTitle(lvRegular, titleToTest) + let lvOther = findChild(controlUnderTest, "otherTokensListView") + verify(!!lvOther) + const bigKittyIndex = findDelegateIndexWithTitle(lvOther, titleToTest) verify(bigKittyIndex !== -1) - const title0 = findChild(lvRegular, "manageTokensDelegate-0").title + const title0 = findChild(lvOther, "manageTokensDelegate-0").title verify(!!title0) verify(title0 !== titleToTest) // trigger move to top and verify we got the correct title - triggerDelegateMenuAction(lvRegular, bigKittyIndex, "miMoveToTop") - waitForItemPolished(lvRegular) - tryCompare(findChild(lvRegular, "manageTokensDelegate-0"), "title", titleToTest) + triggerDelegateMenuAction(lvOther, bigKittyIndex, "miMoveToTop") + waitForItemPolished(lvOther) + tryCompare(findChild(lvOther, "manageTokensDelegate-0"), "title", titleToTest) // save verify(controlUnderTest.dirty) @@ -303,11 +322,11 @@ Item { // load the settings and check BigKitty is still on top controlUnderTest.revert() verify(!controlUnderTest.dirty) - lvRegular = findChild(controlUnderTest, "lvRegularTokens") - verify(!!lvRegular) - waitForItemPolished(lvRegular) - tryVerify(() => lvRegular.count > 0) - const topItem = findChild(lvRegular, "manageTokensDelegate-0") + lvOther = findChild(controlUnderTest, "otherTokensListView") + verify(!!lvOther) + waitForItemPolished(lvOther) + tryVerify(() => lvOther.count > 0) + const topItem = findChild(lvOther, "manageTokensDelegate-0") verify(!!topItem) tryCompare(topItem, "title", titleToTest) } diff --git a/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml b/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml index 4a2cf76b09..baf5b7fc9a 100644 --- a/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml +++ b/ui/StatusQ/src/StatusQ/Controls/StatusSwitch.qml @@ -23,9 +23,9 @@ Switch { implicitWidth: 52 implicitHeight: 28 - anchors.left: parent.left + anchors.left: root.left anchors.leftMargin: root.leftPadding - anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenter: root.verticalCenter Rectangle { anchors.fill: parent @@ -45,8 +45,8 @@ Switch { color: Theme.palette.white layer.enabled: true layer.effect: DropShadow { - width: parent.width - height: parent.height + width: circle.width + height: circle.height visible: true verticalOffset: 1 fast: true diff --git a/ui/app/AppLayouts/Profile/views/SettingsContentBase.qml b/ui/app/AppLayouts/Profile/views/SettingsContentBase.qml index ec2c1d10b0..0b138e41f8 100644 --- a/ui/app/AppLayouts/Profile/views/SettingsContentBase.qml +++ b/ui/app/AppLayouts/Profile/views/SettingsContentBase.qml @@ -28,6 +28,10 @@ FocusScope { property bool saveChangesButtonEnabled: false readonly property alias toast: settingsDirtyToastMessage + readonly property real availableHeight: + scrollView.availableHeight - settingsDirtyToastMessagePlaceholder.height + - Style.current.bigPadding + signal baseAreaClicked() signal saveChangesClicked() signal saveForLaterClicked() @@ -118,7 +122,8 @@ FocusScope { } Item { - // This is a settingsDirtyToastMessage placeholder + id: settingsDirtyToastMessagePlaceholder + width: settingsDirtyToastMessage.implicitWidth height: settingsDirtyToastMessage.active && !root.ignoreDirty ? settingsDirtyToastMessage.implicitHeight : 0 diff --git a/ui/app/AppLayouts/Profile/views/WalletView.qml b/ui/app/AppLayouts/Profile/views/WalletView.qml index 323b39d5a6..3d87c82b59 100644 --- a/ui/app/AppLayouts/Profile/views/WalletView.qml +++ b/ui/app/AppLayouts/Profile/views/WalletView.qml @@ -305,6 +305,10 @@ SettingsContentBase { ManageTokensView { id: manageTokensView + + implicitHeight: root.availableHeight + Layout.fillWidth: true + sourcesOfTokensModel: tokensStore.sourcesOfTokensModel tokensListModel: tokensStore.extendedFlatTokensModel baseWalletAssetsModel: RootStore.walletAssetsStore.groupedAccountAssetsModel diff --git a/ui/app/AppLayouts/Profile/views/wallet/ManageTokensView.qml b/ui/app/AppLayouts/Profile/views/wallet/ManageTokensView.qml index 0d33bc2524..f7433f7e5a 100644 --- a/ui/app/AppLayouts/Profile/views/wallet/ManageTokensView.qml +++ b/ui/app/AppLayouts/Profile/views/wallet/ManageTokensView.qml @@ -17,7 +17,7 @@ import utils 1.0 import AppLayouts.Profile.panels 1.0 import AppLayouts.Wallet.panels 1.0 -ColumnLayout { +Item { id: root required property var sourcesOfTokensModel // Expected roles: key, name, updatedAt, source, version, tokensCount, image @@ -121,157 +121,162 @@ ColumnLayout { } } - StatusTabBar { - id: tabBar + ColumnLayout { + anchors.fill: parent - Layout.fillWidth: true - Layout.topMargin: 5 + StatusTabBar { + id: tabBar - StatusTabButton { - leftPadding: 0 - width: implicitWidth - text: qsTr("Assets") - } - StatusTabButton { - width: implicitWidth - text: qsTr("Collectibles") - } - StatusTabButton { - width: implicitWidth - text: qsTr("Hidden") - } - StatusTabButton { - width: implicitWidth - text: qsTr("Advanced") - } - } + Layout.fillWidth: true + Layout.topMargin: 5 - // NB: we want to discard any pending unsaved changes when switching tabs or navigating away - Loader { - id: loader - Layout.fillWidth: true - Layout.fillHeight: true - active: visible - - sourceComponent: { - switch (tabBar.currentIndex) { - case d.assetsTabIndex: - return tokensPanel - case d.collectiblesTabIndex: - return collectiblesPanel - case d.hiddenTabIndex: - return hiddenPanel - case d.advancedTabIndex: - return advancedTab + StatusTabButton { + leftPadding: 0 + width: implicitWidth + text: qsTr("Assets") + } + StatusTabButton { + width: implicitWidth + text: qsTr("Collectibles") + } + StatusTabButton { + width: implicitWidth + text: qsTr("Hidden") + } + StatusTabButton { + width: implicitWidth + text: qsTr("Advanced") } } - } - Component { - id: tokensPanel - ManageAssetsPanel { - getCurrencyAmount: function (balance, symbol) { - return root.getCurrencyAmount(balance, symbol) - } - getCurrentCurrencyAmount: function (balance) { - return root.getCurrentCurrencyAmount(balance) - } - controller: d.assetsController - } - } + // NB: we want to discard any pending unsaved changes when switching tabs or navigating away + Loader { + id: loader + Layout.fillWidth: true + Layout.fillHeight: true + active: visible - Component { - id: collectiblesPanel - ManageCollectiblesPanel { - controller: d.collectiblesController - Component.onCompleted: d.checkLoadMoreCollectibles() - } - } - - Component { - id: hiddenPanel - ManageHiddenPanel { - getCurrencyAmount: function (balance, symbol) { - return root.getCurrencyAmount(balance, symbol) - } - getCurrentCurrencyAmount: function (balance) { - return root.getCurrentCurrencyAmount(balance) - } - assetsController: d.assetsController - collectiblesController: d.collectiblesController - } - } - - Component { - id: advancedTab - ColumnLayout { - spacing: 8 - StatusListItem { - Layout.fillWidth: true - title: qsTr("Show community assets when sending tokens") - - components: [ - StatusSwitch { - id: showCommunityAssetsSwitch - checked: true // FIXME integrate with backend (#13178) - onCheckedChanged: { - // FIXME integrate with backend (#13178) - } - } - ] - onClicked: { - showCommunityAssetsSwitch.checked = !showCommunityAssetsSwitch.checked + sourceComponent: { + switch (tabBar.currentIndex) { + case d.assetsTabIndex: + return tokensPanel + case d.collectiblesTabIndex: + return collectiblesPanel + case d.hiddenTabIndex: + return hiddenPanel + case d.advancedTabIndex: + return advancedTab } } - StatusDialogDivider { - Layout.fillWidth: true - } - StatusListItem { - Layout.fillWidth: true - title: qsTr("Don’t display assets with balance lower than") + } - components: [ - CurrencyAmountInput { - enabled: displayThresholdSwitch.checked - currencySymbol: SharedStores.RootStore.currencyStore.currentCurrency - value: 0.10 // FIXME integrate with backend (#13178) - }, - StatusSwitch { - id: displayThresholdSwitch - checked: false // FIXME integrate with backend (#13178) - onCheckedChanged: { - // FIXME integrate with backend (#13178) - } - } - ] - onClicked: { - displayThresholdSwitch.checked = !displayThresholdSwitch.checked + Component { + id: tokensPanel + ManageAssetsPanel { + getCurrencyAmount: function (balance, symbol) { + return root.getCurrencyAmount(balance, symbol) } + getCurrentCurrencyAmount: function (balance) { + return root.getCurrentCurrencyAmount(balance) + } + + controller: d.assetsController } - StatusDialogDivider { - Layout.fillWidth: true + } + + Component { + id: collectiblesPanel + ManageCollectiblesPanel { + controller: d.collectiblesController + Component.onCompleted: d.checkLoadMoreCollectibles() } - RowLayout { - Layout.fillWidth: true - Layout.preferredHeight: 64 - Layout.topMargin: 18 - Layout.bottomMargin: 18 - StatusBaseText { + } + + Component { + id: hiddenPanel + ManageHiddenPanel { + getCurrencyAmount: function (balance, symbol) { + return root.getCurrencyAmount(balance, symbol) + } + getCurrentCurrencyAmount: function (balance) { + return root.getCurrentCurrencyAmount(balance) + } + assetsController: d.assetsController + collectiblesController: d.collectiblesController + } + } + + Component { + id: advancedTab + ColumnLayout { + spacing: 8 + StatusListItem { Layout.fillWidth: true - text: qsTr("Token lists") - color: Style.current.textColor + title: qsTr("Show community assets when sending tokens") + + components: [ + StatusSwitch { + id: showCommunityAssetsSwitch + checked: true // FIXME integrate with backend (#13178) + onCheckedChanged: { + // FIXME integrate with backend (#13178) + } + } + ] + onClicked: { + showCommunityAssetsSwitch.checked = !showCommunityAssetsSwitch.checked + } } - StatusBaseText { - Layout.alignment: Qt.AlignRight - text: qsTr("Last updated %1 @%2").arg(LocaleUtils.formatDate(root.sourcesOfTokensModel.get(0).updatedAt * 1000)).arg(LocaleUtils.formatTime(root.sourcesOfTokensModel.get(0).updatedAt, Locale.ShortFormat)) - color: Style.current.darkGrey + StatusDialogDivider { + Layout.fillWidth: true + } + StatusListItem { + Layout.fillWidth: true + title: qsTr("Don’t display assets with balance lower than") + + components: [ + CurrencyAmountInput { + enabled: displayThresholdSwitch.checked + currencySymbol: SharedStores.RootStore.currencyStore.currentCurrency + value: 0.10 // FIXME integrate with backend (#13178) + }, + StatusSwitch { + id: displayThresholdSwitch + checked: false // FIXME integrate with backend (#13178) + onCheckedChanged: { + // FIXME integrate with backend (#13178) + } + } + ] + onClicked: { + displayThresholdSwitch.checked = !displayThresholdSwitch.checked + } + } + StatusDialogDivider { + Layout.fillWidth: true + } + RowLayout { + Layout.fillWidth: true + Layout.preferredHeight: 64 + Layout.topMargin: 18 + Layout.bottomMargin: 18 + StatusBaseText { + Layout.fillWidth: true + text: qsTr("Token lists") + color: Style.current.textColor + } + StatusBaseText { + Layout.alignment: Qt.AlignRight + text: qsTr("Last updated %1 @%2").arg(LocaleUtils.formatDate(root.sourcesOfTokensModel.get(0).updatedAt * 1000)).arg(LocaleUtils.formatTime(root.sourcesOfTokensModel.get(0).updatedAt, Locale.ShortFormat)) + color: Style.current.darkGrey + } + } + SupportedTokenListsPanel { + Layout.fillWidth: true + Layout.fillHeight: true + sourcesOfTokensModel: root.sourcesOfTokensModel + tokensListModel: root.tokensListModel } - } - SupportedTokenListsPanel { - Layout.fillWidth: true - Layout.fillHeight: true - sourcesOfTokensModel: root.sourcesOfTokensModel - tokensListModel: root.tokensListModel } } } diff --git a/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml b/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml index fb72d1f96a..208e37794b 100644 --- a/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml +++ b/ui/app/AppLayouts/Wallet/controls/ManageTokensDelegate.qml @@ -47,13 +47,14 @@ DropArea { keys: isCommunityToken ? ["x-status-draggable-community-token-item"] : ["x-status-draggable-regular-token-item"] width: ListView.view ? ListView.view.width : 0 - height: visible ? delegate.height : 0 + height: delegate.height onEntered: function(drag) { const from = drag.source.visualIndex const to = delegate.visualIndex if (to === from) return + ListView.view.model.moveItem(from, to) drag.accept() } diff --git a/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml b/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml index 7e7a9e4795..dc64e529d5 100644 --- a/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml +++ b/ui/app/AppLayouts/Wallet/controls/ManageTokensGroupDelegate.qml @@ -35,7 +35,7 @@ DropArea { keys: isCollection ? ["x-status-draggable-collection-group-item"] : ["x-status-draggable-community-group-item"] width: ListView.view ? ListView.view.width : 0 - height: visible ? groupedCommunityTokenDelegate.implicitHeight : 0 + height: groupedCommunityTokenDelegate.implicitHeight onEntered: function(drag) { const from = drag.source.visualIndex diff --git a/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml b/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml index 79d455e177..7ff89237f5 100644 --- a/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/ManageAssetsPanel.qml @@ -1,17 +1,22 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 +import QtQml.Models 2.15 +import QtQml 2.15 -import StatusQ.Core 0.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.Models 0.1 -import utils 1.0 +import shared.controls 1.0 import AppLayouts.Wallet.controls 1.0 +import "internals" + Control { id: root @@ -37,18 +42,35 @@ Control { root.controller.clearSettings(); } + QtObject { + id: d - contentItem: ColumnLayout { - spacing: Style.current.padding + readonly property int sectionHeight: 64 + } - StatusListView { - Layout.fillWidth: true + contentItem: DoubleFlickableWithFolding { + id: doubleFlickable + + clip: true + + ScrollBar.vertical: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, doubleFlickable.height, + doubleFlickable.contentHeight) + } + + flickable1: ManageTokensListViewBase { model: root.controller.regularTokensModel - implicitHeight: contentHeight - interactive: false + width: doubleFlickable.width - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } + ScrollBar.vertical: null + + header: FoldableHeader { + width: ListView.view.width + title: qsTr("Assets") + folded: doubleFlickable.flickable1Folded + + onToggleFolding: doubleFlickable.flip1Folding() } delegate: ManageTokensDelegate { @@ -63,78 +85,69 @@ Control { return root.getCurrentCurrencyAmount(balance) } } + + placeholderText: qsTr("Your assets will appear here") } - RowLayout { - Layout.fillWidth: true - Layout.topMargin: Style.current.padding - visible: root.controller.communityTokensModel.count - StatusBaseText { - Layout.fillWidth: true - text: qsTr("Community") - } - StatusSwitch { - LayoutMirroring.enabled: true - LayoutMirroring.childrenInherit: true - id: switchArrangeByCommunity - textColor: Theme.palette.baseColor1 - font.pixelSize: 13 - text: qsTr("Arrange by community") + flickable2: ManageTokensListViewBase { + width: doubleFlickable.width + + model: root.controller.arrangeByCommunity ? communityGroupedModel + : communityNonGroupedModel + + header: FoldableHeader { + width: ListView.view.width + title: qsTr("Community minted") + switchText: qsTr("Arrange by community") + folded: doubleFlickable.flickable2Folded checked: root.controller.arrangeByCommunity - onToggled: root.controller.arrangeByCommunity = checked - } - } - Loader { - Layout.fillWidth: true - active: root.controller.communityTokensModel.count - visible: active - sourceComponent: switchArrangeByCommunity.checked ? cmpCommunityTokenGroups : cmpCommunityTokens + onToggleFolding: doubleFlickable.flip2Folding() + onToggleSwitch: root.controller.arrangeByCommunity = checked + } + + placeholderText: qsTr("Your community minted assets will appear here") } } - Component { - id: cmpCommunityTokens - StatusListView { - model: root.controller.communityTokensModel - implicitHeight: contentHeight - interactive: false + DelegateModel { + id: communityNonGroupedModel - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } + model: root.controller.communityTokensModel + + function moveItem(from, to) { + model.moveItem(from, to) + } + + delegate: ManageTokensDelegate { + controller: root.controller + dragParent: root + count: root.controller.communityTokensModel.count + dragEnabled: count > 1 + getCurrencyAmount: function (balance, symbol) { + return root.getCurrencyAmount(balance, symbol) } - - delegate: ManageTokensDelegate { - controller: root.controller - dragParent: root - count: root.controller.communityTokensModel.count - dragEnabled: count > 1 - getCurrencyAmount: function (balance, symbol) { - return root.getCurrencyAmount(balance, symbol) - } - getCurrentCurrencyAmount: function (balance) { - return root.getCurrentCurrencyAmount(balance) - } + getCurrentCurrencyAmount: function (balance) { + return root.getCurrentCurrencyAmount(balance) } } } - Component { - id: cmpCommunityTokenGroups - StatusListView { - model: root.controller.communityTokenGroupsModel - implicitHeight: contentHeight - interactive: false + DelegateModel { + id: communityGroupedModel - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } - } + model: root.controller.communityTokenGroupsModel - delegate: ManageTokensGroupDelegate { - controller: root.controller - dragParent: root - dragEnabled: root.controller.communityTokenGroupsModel.count > 1 - } + function moveItem(from, to) { + model.moveItem(from, to) + } + + delegate: ManageTokensGroupDelegate { + height: 76 + + controller: root.controller + dragParent: root + dragEnabled: root.controller.communityTokenGroupsModel.count > 1 } } } diff --git a/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml b/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml index 466f6b22fa..8b6c25804c 100644 --- a/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/ManageCollectiblesPanel.qml @@ -1,19 +1,16 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 +import QtQml.Models 2.15 -import StatusQ 0.1 -import StatusQ.Core 0.1 -import StatusQ.Components 0.1 import StatusQ.Controls 0.1 import StatusQ.Core.Theme 0.1 -import StatusQ.Models 0.1 - -import utils 1.0 -import shared.controls 1.0 +import StatusQ.Core.Utils 0.1 import AppLayouts.Wallet.controls 1.0 +import "internals" + Control { id: root @@ -36,157 +33,133 @@ Control { root.controller.clearSettings(); } - contentItem: ColumnLayout { - spacing: Style.current.padding + contentItem: DoubleFlickableWithFolding { + id: doubleFlickable - ShapeRectangle { - Layout.fillWidth: true - Layout.margins: 2 - visible: !root.controller.regularTokensModel.count && !root.controller.communityTokensModel.count - text: qsTr("You’ll be able to manage the display of your collectibles here") + clip: true + + ScrollBar.vertical: StatusScrollBar { + policy: ScrollBar.AsNeeded + visible: resolveVisibility(policy, doubleFlickable.height, + doubleFlickable.contentHeight) } - RowLayout { - Layout.fillWidth: true - Layout.topMargin: Style.current.padding - visible: root.controller.communityTokensModel.count - StatusBaseText { - Layout.fillWidth: true - text: qsTr("Community minted") - } - StatusSwitch { - objectName: "switchArrangeByCommunity" - LayoutMirroring.enabled: true - LayoutMirroring.childrenInherit: true - id: switchArrangeByCommunity - textColor: Theme.palette.baseColor1 - font.pixelSize: 13 - text: qsTr("Arrange by community") + flickable1: ManageTokensListViewBase { + objectName: "communityTokensListView" + + width: doubleFlickable.width + + model: root.controller.arrangeByCommunity + ? communityGroupedModel : communityNonGroupedModel + + header: FoldableHeader { + objectName: "communityHeader" + + width: ListView.view.width + title: qsTr("Community minted") + switchText: qsTr("Arrange by community") + folded: doubleFlickable.flickable1Folded checked: root.controller.arrangeByCommunity - onToggled: root.controller.arrangeByCommunity = checked + + onToggleFolding: doubleFlickable.flip1Folding() + onToggleSwitch: root.controller.arrangeByCommunity = checked } + + placeholderText: qsTr("Your community minted collectibles will appear here") } - Loader { - objectName: "loaderCommunityTokens" - Layout.fillWidth: true - active: root.controller.communityTokensModel.count - visible: active - sourceComponent: switchArrangeByCommunity.checked ? cmpCommunityTokenGroups : cmpCommunityTokens - } + flickable2: ManageTokensListViewBase { + objectName: "otherTokensListView" - RowLayout { - Layout.fillWidth: true - Layout.topMargin: Style.current.padding - visible: root.controller.regularTokensModel.count - StatusBaseText { - Layout.fillWidth: true - text: qsTr("Other") - } - StatusSwitch { - LayoutMirroring.enabled: true - LayoutMirroring.childrenInherit: true - id: switchArrangeByCollection - textColor: Theme.palette.baseColor1 - font.pixelSize: 13 - text: qsTr("Arrange by collection") + width: doubleFlickable.width + + model: root.controller.arrangeByCollection + ? otherGroupedModel : otherNonGroupedModel + + header: FoldableHeader { + objectName: "nonCommunityHeader" + + width: ListView.view.width + title: qsTr("Other") + switchText: qsTr("Arrange by collection") + folded: doubleFlickable.flickable2Folded checked: root.controller.arrangeByCollection - onToggled: root.controller.arrangeByCollection = checked - } - } - Loader { - objectName: "loaderRegularTokens" - Layout.fillWidth: true - active: root.controller.regularTokensModel.count - visible: active - sourceComponent: switchArrangeByCollection.checked ? cmpCollectionTokenGroups : cmpRegularTokens + onToggleFolding: doubleFlickable.flip2Folding() + onToggleSwitch: root.controller.arrangeByCollection = checked + } + + placeholderText: qsTr("Your other collectibles will appear here") } } - Component { - id: cmpCommunityTokens - StatusListView { - objectName: "lvCommunityTokens" - model: root.controller.communityTokensModel - implicitHeight: contentHeight - interactive: false + DelegateModel { + id: communityNonGroupedModel - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } - } + model: root.controller.communityTokensModel - delegate: ManageTokensDelegate { - isCollectible: true - controller: root.controller - dragParent: root - count: root.controller.communityTokensModel.count - dragEnabled: count > 1 - } + function moveItem(from, to) { + model.moveItem(from, to) + } + + delegate: ManageTokensDelegate { + isCollectible: true + controller: root.controller + dragParent: root + count: root.controller.communityTokensModel.count + dragEnabled: count > 1 } } - Component { - id: cmpCommunityTokenGroups - StatusListView { - objectName: "lvCommunityTokenGroups" - model: root.controller.communityTokenGroupsModel - implicitHeight: contentHeight - interactive: false + DelegateModel { + id: communityGroupedModel - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } - } + model: root.controller.communityTokenGroupsModel - delegate: ManageTokensGroupDelegate { - isCollectible: true - controller: root.controller - dragParent: root - dragEnabled: root.controller.communityTokenGroupsModel.count > 1 - } + function moveItem(from, to) { + model.moveItem(from, to) + } + + delegate: ManageTokensGroupDelegate { + isCollectible: true + controller: root.controller + dragParent: root + dragEnabled: root.controller.communityTokenGroupsModel.count > 1 } } - Component { - id: cmpRegularTokens - StatusListView { - objectName: "lvRegularTokens" - model: root.controller.regularTokensModel - implicitHeight: contentHeight - interactive: false + DelegateModel { + id: otherNonGroupedModel - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } - } + model: root.controller.regularTokensModel - delegate: ManageTokensDelegate { - isCollectible: true - controller: root.controller - dragParent: root - count: root.controller.regularTokensModel.count - dragEnabled: count > 1 - } + function moveItem(from, to) { + model.moveItem(from, to) + } + + delegate: ManageTokensDelegate { + isCollectible: true + controller: root.controller + dragParent: root + count: root.controller.regularTokensModel.count + dragEnabled: count > 1 } } - Component { - id: cmpCollectionTokenGroups - StatusListView { - objectName: "lvCollectionTokenGroups" - model: root.controller.collectionGroupsModel - implicitHeight: contentHeight - interactive: false + DelegateModel { + id: otherGroupedModel - displaced: Transition { - NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } - } + model: root.controller.collectionGroupsModel - delegate: ManageTokensGroupDelegate { - isCollection: true - controller: root.controller - dragParent: root - dragEnabled: root.controller.collectionGroupsModel.count > 1 - } + function moveItem(from, to) { + model.moveItem(from, to) + } + + delegate: ManageTokensGroupDelegate { + isCollection: true + controller: root.controller + dragParent: root + dragEnabled: root.controller.collectionGroupsModel.count > 1 } } } diff --git a/ui/app/AppLayouts/Wallet/panels/ManageHiddenPanel.qml b/ui/app/AppLayouts/Wallet/panels/ManageHiddenPanel.qml index 69822c82db..0e9bd7e570 100644 --- a/ui/app/AppLayouts/Wallet/panels/ManageHiddenPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/ManageHiddenPanel.qml @@ -184,6 +184,8 @@ Control { ColumnLayout { // no assets placeholder Layout.fillWidth: true + Layout.fillHeight: false + spacing: 0 visible: !d.assetsCount SectionDelegate { @@ -196,9 +198,11 @@ Control { } StatusListView { + id: listView + Layout.fillWidth: true - implicitHeight: contentHeight Layout.fillHeight: true + model: d.sfpm displaced: Transition { @@ -221,21 +225,29 @@ Control { isCollectible: section == "true" } section.labelPositioning: ViewSection.InlineLabels | ViewSection.CurrentLabelAtStart + + footer: ColumnLayout { // no collectibles placeholder + width: ListView.view.width + + spacing: 0 + visible: !d.collectiblesCount + height: visible ? implicitHeight : 0 + + SectionDelegate { + Layout.fillWidth: true + isCollectible: true + } + Placeholder { + Layout.fillWidth: true + isCollectible: true + visible: d.collectiblesExpanded + } + } } - ColumnLayout { // no collectibles placeholder - Layout.fillWidth: true - spacing: 0 - visible: !d.collectiblesCount - SectionDelegate { - Layout.fillWidth: true - isCollectible: true - } - Placeholder { - Layout.fillWidth: true - isCollectible: true - visible: d.collectiblesExpanded - } + Item { + Layout.fillHeight: true + visible: listView.count === 0 } } } diff --git a/ui/app/AppLayouts/Wallet/panels/internals/FoldableHeader.qml b/ui/app/AppLayouts/Wallet/panels/internals/FoldableHeader.qml new file mode 100644 index 0000000000..3848b45a50 --- /dev/null +++ b/ui/app/AppLayouts/Wallet/panels/internals/FoldableHeader.qml @@ -0,0 +1,64 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 + +import StatusQ.Controls 0.1 +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 + +Rectangle { + id: root + + property bool folded: false + property alias title: label.text + property alias switchText: modeSwitch.text + property alias checked: modeSwitch.checked + + signal toggleFolding + signal toggleSwitch + + height: headerContent.height + z: 1 + + color: Theme.palette.statusListItem.backgroundColor + + QtObject { + id: d + + readonly property int sectionHeight: 64 + } + + RowLayout { + id: headerContent + + width: parent.width + height: d.sectionHeight + + StatusFlatButton { + checkable: true + size: StatusBaseButton.Size.Small + icon.name: checked ? "chevron-down" : "next" + textColor: Theme.palette.baseColor1 + textHoverColor: Theme.palette.directColor1 + + checked: !root.folded + onToggled: root.toggleFolding() + } + + StatusBaseText { + id: label + + Layout.fillWidth: true + } + StatusSwitch { + id: modeSwitch + objectName: "switch" + + visible: !!text + LayoutMirroring.enabled: true + LayoutMirroring.childrenInherit: true + textColor: Theme.palette.baseColor1 + font.pixelSize: 13 + onToggled: root.toggleSwitch() + } + } +} diff --git a/ui/app/AppLayouts/Wallet/panels/internals/ManageTokensListViewBase.qml b/ui/app/AppLayouts/Wallet/panels/internals/ManageTokensListViewBase.qml new file mode 100644 index 0000000000..7aec75ffdc --- /dev/null +++ b/ui/app/AppLayouts/Wallet/panels/internals/ManageTokensListViewBase.qml @@ -0,0 +1,51 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQml 2.15 + +import StatusQ.Controls 0.1 +import StatusQ.Core 0.1 +import QtQuick.Controls 2.15 +import StatusQ.Core.Theme 0.1 + +import shared.controls 1.0 + +StatusListView { + id: root + + property string placeholderText + + ScrollBar.vertical: null + + QtObject { + id: d + + readonly property int placeholderHeight: 44 + } + + Binding { + when: root.model && root.count === 0 + target: root + property: "footer" + restoreMode: Binding.RestoreBindingOrValue + + value: Component { + Item { + height: d.placeholderHeight + width: root.width + + ShapeRectangle { + id: shapeRectangle + + text: root.placeholderText + + anchors.fill: parent + anchors.margins: 1 + } + } + } + } + + displaced: Transition { + NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } + } +}