feat(ProfileShowcase): Add foldable sections in profile showcase tabs

- Modified `ProfileShowcasePanel` with 2 foldable sections.
-  Modified api of `ProfileShowcaseCommunitiesPanel` with the new base component.
- Modified api of `ProfileShowcaseAccountsPanel` with the new base component.
- Modified api of `ProfileShowcaseAssetsPanel`  and `ProfileShowcaseCollectiblesPanel` with the new base component.
- Added needed `storybook` support.

Closes of #13504
This commit is contained in:
Noelia 2024-02-15 18:26:05 +01:00 committed by Noelia
parent 9c3159ecd1
commit 01095e0208
10 changed files with 359 additions and 325 deletions

View File

@ -1,5 +1,6 @@
import QtQuick 2.14 import QtQuick 2.14
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1 as CoreUtils import StatusQ.Core.Utils 0.1 as CoreUtils
@ -28,6 +29,10 @@ SplitView {
readonly property string currentWallet: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7420" readonly property string currentWallet: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7420"
ListModel {
id: emptyModel
}
ListModel { ListModel {
id: accountsModel id: accountsModel
@ -52,18 +57,13 @@ SplitView {
emoji: "🇸🇰" emoji: "🇸🇰"
walletType: "watch" walletType: "watch"
} }
ListElement {
name: "Keycard"
address: "0xdeadbeef"
colorId: "turquoise"
emoji: ""
walletType: "key"
}
} }
ListModel { ListModel {
id: inShowcaseAccountsModel id: inShowcaseAccountsModel
property int hiddenCount: emptyModelChecker.checked ? 0 : accountsModel.count - count
signal baseModelFilterConditionsMayHaveChanged() signal baseModelFilterConditionsMayHaveChanged()
function setVisibilityByIndex(index, visibility) { function setVisibilityByIndex(index, visibility) {
@ -102,7 +102,7 @@ SplitView {
ProfileShowcaseAccountsPanel { ProfileShowcaseAccountsPanel {
id: showcasePanel id: showcasePanel
width: 500 width: 500
baseModel: accountsModel baseModel: emptyModelChecker.checked ? emptyModel : accountsModel
showcaseModel: inShowcaseAccountsModel showcaseModel: inShowcaseAccountsModel
currentWallet: root.currentWallet currentWallet: root.currentWallet
} }
@ -116,15 +116,25 @@ SplitView {
logsView.logText: logs.logText logsView.logText: logs.logText
ColumnLayout {
Button { Button {
text: "Reset (clear settings)" text: "Reset (clear settings)"
onClicked: showcasePanel.settings.reset() onClicked: showcasePanel.reset()
}
CheckBox {
id: emptyModelChecker
text: "Empty model"
checked: false
onClicked: showcasePanel.reset()
}
} }
} }
} }
// category: Panels // category: Panels
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=14580-339549&t=RkXAEv3G6mp3EUvl-0 // https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?type=design&node-id=2460%3A40333&mode=design&t=Zj3tcx9uj05XHYti-1
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=14729-233846&t=RkXAEv3G6mp3EUvl-0 // https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?type=design&node-id=2460%3A40362&mode=design&t=Zj3tcx9uj05XHYti-1
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=14609-237740&t=RkXAEv3G6mp3EUvl-0

View File

@ -33,9 +33,15 @@ SplitView {
assetsWithFilteredBalances: walletAssetStore.groupedAccountsAssetsModel assetsWithFilteredBalances: walletAssetStore.groupedAccountsAssetsModel
} }
ListModel {
id: emptyModel
}
ListModel { ListModel {
id: inShowcaseAssetsModel id: inShowcaseAssetsModel
property int hiddenCount: emptyModelChecker.checked ? 0 : walletAssetStore.groupedAccountsAssetsModel.count - count
signal baseModelFilterConditionsMayHaveChanged() signal baseModelFilterConditionsMayHaveChanged()
function setVisibilityByIndex(index, visibility) { function setVisibilityByIndex(index, visibility) {
@ -75,7 +81,7 @@ SplitView {
ProfileShowcaseAssetsPanel { ProfileShowcaseAssetsPanel {
id: showcasePanel id: showcasePanel
width: 500 width: 500
baseModel: walletAssetStore.groupedAccountAssetsModel baseModel: emptyModelChecker.checked ? emptyModel : walletAssetStore.groupedAccountAssetsModel
showcaseModel: inShowcaseAssetsModel showcaseModel: inShowcaseAssetsModel
addAccountsButtonVisible: !hasAllAccountsChecker.checked addAccountsButtonVisible: !hasAllAccountsChecker.checked
@ -111,6 +117,15 @@ SplitView {
text: "Has the user already shared all of their accounts" text: "Has the user already shared all of their accounts"
checked: true checked: true
} }
CheckBox {
id: emptyModelChecker
text: "Empty model"
checked: false
onClicked: showcasePanel.reset()
}
} }
} }
} }

View File

@ -29,6 +29,10 @@ SplitView {
communityTokensStore: CommunityTokensStore {} communityTokensStore: CommunityTokensStore {}
} }
ListModel {
id: emptyModel
}
ListModel { ListModel {
id: collectiblesModel id: collectiblesModel
@ -124,6 +128,8 @@ SplitView {
ListModel { ListModel {
id: inShowcaseCollectiblesModel id: inShowcaseCollectiblesModel
property int hiddenCount: emptyModelChecker.checked ? 0 : collectiblesModel.count - count
signal baseModelFilterConditionsMayHaveChanged() signal baseModelFilterConditionsMayHaveChanged()
function setVisibilityByIndex(index, visibility) { function setVisibilityByIndex(index, visibility) {
@ -162,7 +168,7 @@ SplitView {
ProfileShowcaseCollectiblesPanel { ProfileShowcaseCollectiblesPanel {
id: showcasePanel id: showcasePanel
width: 500 width: 500
baseModel: leftJoinModel baseModel: emptyModelChecker.checked ? emptyModel : leftJoinModel
showcaseModel: inShowcaseCollectiblesModel showcaseModel: inShowcaseCollectiblesModel
addAccountsButtonVisible: !hasAllAccountsChecker.checked addAccountsButtonVisible: !hasAllAccountsChecker.checked
@ -192,6 +198,15 @@ SplitView {
checked: true checked: true
} }
CheckBox {
id: emptyModelChecker
text: "Empty model"
checked: false
onClicked: showcasePanel.reset()
}
} }
} }
} }

View File

@ -1,11 +1,13 @@
import QtQuick 2.14 import QtQuick 2.14
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1 as CoreUtils import StatusQ.Core.Utils 0.1 as CoreUtils
import mainui 1.0 import mainui 1.0
import AppLayouts.Profile.panels 1.0 import AppLayouts.Profile.panels 1.0
import AppLayouts.Profile.controls 1.0
import shared.stores 1.0 import shared.stores 1.0
import utils 1.0 import utils 1.0
@ -26,6 +28,10 @@ SplitView {
communityTokensStore: CommunityTokensStore {} communityTokensStore: CommunityTokensStore {}
} }
ListModel {
id: emptyModel
}
ListModel { ListModel {
id: communitiesModel id: communitiesModel
@ -48,15 +54,6 @@ SplitView {
image: ModelsData.collectibles.custom, image: ModelsData.collectibles.custom,
color: "peach" color: "peach"
}, },
{
id: "0x0003",
name: "Test community invisible",
joined: false,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: "",
color: "red"
},
{ {
id: "0x0004", id: "0x0004",
name: "Test community 3", name: "Test community 3",
@ -81,6 +78,8 @@ SplitView {
ListModel { ListModel {
id: inShowcaseCommunitiesModel id: inShowcaseCommunitiesModel
property int hiddenCount: emptyModelChecker.checked ? 0 : communitiesModel.count - count
signal baseModelFilterConditionsMayHaveChanged() signal baseModelFilterConditionsMayHaveChanged()
function setVisibilityByIndex(index, visibility) { function setVisibilityByIndex(index, visibility) {
@ -116,10 +115,11 @@ SplitView {
StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml
SplitView.fillWidth: true SplitView.fillWidth: true
SplitView.preferredHeight: 500 SplitView.preferredHeight: 500
ProfileShowcaseCommunitiesPanel { ProfileShowcaseCommunitiesPanel {
id: showcasePanel id: showcasePanel
width: 500 width: 500
baseModel: communitiesModel baseModel: emptyModelChecker.checked ? emptyModel : communitiesModel
showcaseModel: inShowcaseCommunitiesModel showcaseModel: inShowcaseCommunitiesModel
} }
} }
@ -132,9 +132,20 @@ SplitView {
logsView.logText: logs.logText logsView.logText: logs.logText
ColumnLayout {
Button { Button {
text: "Reset (clear settings)" text: "Reset (clear settings)"
onClicked: showcasePanel.settings.reset() onClicked: showcasePanel.reset()
}
CheckBox {
id: emptyModelChecker
text: "Empty model"
checked: false
onClicked: showcasePanel.reset()
}
} }
} }
} }

View File

@ -12,10 +12,10 @@ ProfileShowcasePanel {
keyRole: "address" keyRole: "address"
roleNames: ["address", "name", "walletType", "emoji", "colorId"].concat(showcaseRoles) roleNames: ["address", "name", "walletType", "emoji", "colorId"].concat(showcaseRoles)
filterFunc: (modelData) => modelData.walletType !== Constants.keyWalletType && !showcaseModel.hasItemInShowcase(modelData.address) filterFunc: (modelData) => modelData.walletType !== Constants.keyWalletType && !showcaseModel.hasItemInShowcase(modelData.address)
hiddenPlaceholderBanner: qsTr("Accounts here will show on your profile") emptyInShowcasePlaceholderText: qsTr("Accounts here will show on your profile")
showcasePlaceholderBanner: qsTr("Accounts here will be hidden from your profile") emptyHiddenPlaceholderText: qsTr("Accounts here will be hidden from your profile")
draggableDelegateComponent: AccountShowcaseDelegate { hiddenDraggableDelegateComponent: AccountShowcaseDelegate {
Drag.keys: ["x-status-draggable-showcase-item-hidden"] Drag.keys: ["x-status-draggable-showcase-item-hidden"]
showcaseObj: modelData showcaseObj: modelData
dragParent: dragParentData dragParent: dragParentData

View File

@ -21,10 +21,10 @@ ProfileShowcasePanel {
keyRole: "symbol" keyRole: "symbol"
roleNames: ["symbol", "name", "address", "communityId", "enabledNetworkBalance", "decimals"].concat(showcaseRoles) roleNames: ["symbol", "name", "address", "communityId", "enabledNetworkBalance", "decimals"].concat(showcaseRoles)
filterFunc: (modelData) => modelData.symbol !== "" && !showcaseModel.hasItemInShowcase(modelData.symbol) filterFunc: (modelData) => modelData.symbol !== "" && !showcaseModel.hasItemInShowcase(modelData.symbol)
hiddenPlaceholderBanner: qsTr("Assets here will show on your profile") emptyInShowcasePlaceholderText: qsTr("Assets here will show on your profile")
showcasePlaceholderBanner: qsTr("Assets here will be hidden from your profile") emptyHiddenPlaceholderText: qsTr("Assets here will be hidden from your profile")
draggableDelegateComponent: AssetShowcaseDelegate { hiddenDraggableDelegateComponent: AssetShowcaseDelegate {
Drag.keys: ["x-status-draggable-showcase-item-hidden"] Drag.keys: ["x-status-draggable-showcase-item-hidden"]
showcaseObj: modelData showcaseObj: modelData
dragParent: dragParentData dragParent: dragParentData
@ -52,15 +52,17 @@ ProfileShowcasePanel {
root.showcaseEntryChanged() root.showcaseEntryChanged()
} }
} }
additionalComponent: root.addAccountsButtonVisible ? addMoreAccountsComponent : null
Component { // TODO: Issue #13590
id: addMoreAccountsComponent // additionalComponent: root.addAccountsButtonVisible ? addMoreAccountsComponent : null
AddMoreAccountsLink { // Component {
visible: root.addAccountsButtonVisible // id: addMoreAccountsComponent
text: qsTr("Dont see some of your assets?")
onClicked: root.navigateToAccountsTab() // AddMoreAccountsLink {
} // visible: root.addAccountsButtonVisible
} // text: qsTr("Dont see some of your assets?")
// onClicked: root.navigateToAccountsTab()
// }
// }
} }

View File

@ -19,10 +19,10 @@ ProfileShowcasePanel {
keyRole: "uid" keyRole: "uid"
roleNames: ["uid", "chainId", "tokenId", "contractAddress", "communityId", "name", "collectionName", "backgroundColor", "imageUrl"].concat(showcaseRoles) roleNames: ["uid", "chainId", "tokenId", "contractAddress", "communityId", "name", "collectionName", "backgroundColor", "imageUrl"].concat(showcaseRoles)
filterFunc: (modelData) => !showcaseModel.hasItemInShowcase(modelData.uid) filterFunc: (modelData) => !showcaseModel.hasItemInShowcase(modelData.uid)
hiddenPlaceholderBanner: qsTr("Collectibles here will show on your profile") emptyInShowcasePlaceholderText: qsTr("Collectibles here will show on your profile")
showcasePlaceholderBanner: qsTr("Collectibles here will be hidden from your profile") emptyHiddenPlaceholderText: qsTr("Collectibles here will be hidden from your profile")
draggableDelegateComponent: CollectibleShowcaseDelegate { hiddenDraggableDelegateComponent: CollectibleShowcaseDelegate {
Drag.keys: ["x-status-draggable-showcase-item-hidden"] Drag.keys: ["x-status-draggable-showcase-item-hidden"]
showcaseObj: modelData showcaseObj: modelData
dragParent: dragParentData dragParent: dragParentData
@ -47,15 +47,17 @@ ProfileShowcasePanel {
root.showcaseEntryChanged() root.showcaseEntryChanged()
} }
} }
additionalComponent: root.addAccountsButtonVisible ? addMoreAccountsComponent : null
Component { // TODO: Issue #13590
id: addMoreAccountsComponent // additionalComponent: root.addAccountsButtonVisible ? addMoreAccountsComponent : null
AddMoreAccountsLink { // Component {
visible: root.addAccountsButtonVisible // id: addMoreAccountsComponent
text: qsTr("Dont see some of your collectibles?")
onClicked: root.navigateToAccountsTab() // AddMoreAccountsLink {
} // visible: root.addAccountsButtonVisible
} // text: qsTr("Dont see some of your collectibles?")
// onClicked: root.navigateToAccountsTab()
// }
// }
} }

View File

@ -9,11 +9,11 @@ ProfileShowcasePanel {
keyRole: "id" keyRole: "id"
roleNames: ["id", "name", "memberRole", "image", "color"].concat(showcaseRoles) roleNames: ["id", "name", "memberRole", "image", "color"].concat(showcaseRoles)
filterFunc: (modelData) => modelData.joined && !showcaseModel.hasItemInShowcase(modelData.id) filterFunc: (modelData) => modelData.joined && !root.showcaseModel.hasItemInShowcase(modelData.id)
hiddenPlaceholderBanner: qsTr("Communities here will show on your profile") emptyInShowcasePlaceholderText: qsTr("Drag communities here to display in showcase")
showcasePlaceholderBanner: qsTr("Communities here will be hidden from your profile") emptyHiddenPlaceholderText: qsTr("Communities here will be hidden from your Profile")
draggableDelegateComponent: CommunityShowcaseDelegate { hiddenDraggableDelegateComponent: CommunityShowcaseDelegate {
Drag.keys: ["x-status-draggable-showcase-item-hidden"] Drag.keys: ["x-status-draggable-showcase-item-hidden"]
showcaseObj: modelData showcaseObj: modelData
dragParent: dragParentData dragParent: dragParentData
@ -22,7 +22,7 @@ ProfileShowcasePanel {
var tmpObj = Object() var tmpObj = Object()
root.roleNames.forEach(role => tmpObj[role] = showcaseObj[role]) root.roleNames.forEach(role => tmpObj[role] = showcaseObj[role])
tmpObj.showcaseVisibility = value tmpObj.showcaseVisibility = value
showcaseModel.upsertItemJson(JSON.stringify(tmpObj)) root.showcaseModel.upsertItemJson(JSON.stringify(tmpObj))
root.showcaseEntryChanged() root.showcaseEntryChanged()
} }
} }
@ -34,7 +34,7 @@ ProfileShowcasePanel {
dragAxis: Drag.YAxis dragAxis: Drag.YAxis
showcaseVisibility: !!modelData ? modelData.showcaseVisibility : Constants.ShowcaseVisibility.NoOne showcaseVisibility: !!modelData ? modelData.showcaseVisibility : Constants.ShowcaseVisibility.NoOne
onShowcaseVisibilityRequested: { onShowcaseVisibilityRequested: {
showcaseModel.setVisibility(showcaseObj.id, value) root.showcaseModel.setVisibility(showcaseObj.id, value)
root.showcaseEntryChanged() root.showcaseEntryChanged()
} }
} }

View File

@ -1,122 +1,56 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQml 2.15
import StatusQ.Core 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Components 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1
import shared.controls 1.0 import shared.controls 1.0
import utils 1.0 import utils 1.0
import AppLayouts.Profile.controls 1.0 import AppLayouts.Profile.controls 1.0
Control { DoubleFlickableWithFolding {
id: root id: root
readonly property var showcaseRoles: ["showcaseVisibility", "order"]
required property string keyRole
required property var roleNames
required property var filterFunc
property var baseModel property var baseModel
property var showcaseModel property var showcaseModel
readonly property var showcaseRoles: ["showcaseVisibility", "order"]
// to override
property string keyRole
property var roleNames: []
property var filterFunc: (modelData) => true
property string hiddenPlaceholderBanner
property string showcasePlaceholderBanner
property Component draggableDelegateComponent
property Component showcaseDraggableDelegateComponent property Component showcaseDraggableDelegateComponent
property Component additionalComponent property Component hiddenDraggableDelegateComponent
signal showcaseEntryChanged() property string emptyInShowcasePlaceholderText
property string emptyHiddenPlaceholderText
function reset() {
showcaseModel.clear()
updateBaseModelFilters()
}
function updateBaseModelFilters() {
// Reset base model to update filter conditions
hiddenItemsListView.model = null
hiddenItemsListView.model = baseModel
}
readonly property Connections showcaseUpdateConnections: Connections { readonly property Connections showcaseUpdateConnections: Connections {
target: showcaseModel target: root.showcaseModel
function onBaseModelFilterConditionsMayHaveChanged() { function onBaseModelFilterConditionsMayHaveChanged() {
root.updateBaseModelFilters() root.updateBaseModelFilters()
} }
} }
background: null function reset() {
root.showcaseModel.clear()
component VisibilityDropArea: AbstractButton { updateBaseModelFilters()
id: visibilityDropAreaLocal
property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne
readonly property alias containsDrag: dropArea.containsDrag
padding: Style.current.halfPadding
spacing: padding/2
icon.color: Theme.palette.primaryColor1
background: ShapeRectangle {
path.strokeColor: dropArea.containsDrag ? "transparent" : Theme.palette.directColor7
path.fillColor: dropArea.containsDrag ? Theme.palette.white : "transparent"
DropArea {
id: dropArea
anchors.fill: parent
keys: ["x-status-draggable-showcase-item-hidden"]
onEntered: function(drag) {
drag.accept()
} }
onDropped: function(drop) { function updateBaseModelFilters() {
var showcaseObj = drop.source.showcaseObj // Reset base model to update filter conditions
hiddenListView.model = null
// need to set total balance for an asset hiddenListView.model = root.baseModel
if (drop.source.totalValue !== undefined) {
showcaseObj.enabledNetworkBalance = drop.source.totalValue
} }
var tmpObj = Object() signal showcaseEntryChanged()
root.roleNames.forEach(role => tmpObj[role] = showcaseObj[role])
tmpObj.showcaseVisibility = visibilityDropAreaLocal.showcaseVisibility
showcaseModel.upsertItemJson(JSON.stringify(tmpObj))
root.showcaseEntryChanged()
}
}
}
contentItem: Item {
RowLayout {
width: Math.min(parent.width, implicitWidth)
anchors.centerIn: parent
spacing: visibilityDropAreaLocal.spacing
StatusIcon {
width: 20
height: 20
icon: ProfileUtils.visibilityIcon(visibilityDropAreaLocal.showcaseVisibility)
color: visibilityDropAreaLocal.icon.color
}
StatusBaseText {
Layout.fillWidth: true
font.pixelSize: 13
font.weight: Font.Medium
elide: Text.ElideRight
color: visibilityDropAreaLocal.icon.color
text: visibilityDropAreaLocal.text
}
}
}
}
QtObject { QtObject {
id: d id: d
@ -124,29 +58,30 @@ Control {
readonly property int defaultDelegateHeight: 60 readonly property int defaultDelegateHeight: 60
readonly property int contentSpacing: 12 readonly property int contentSpacing: 12
readonly property int strokeMargin: 2 readonly property int strokeMargin: 2
readonly property int shapeRectangleHeight: 48
} }
contentItem: ColumnLayout { clip: true
spacing: d.contentSpacing
StatusBaseText { ScrollBar.vertical: StatusScrollBar {
Layout.fillWidth: true policy: ScrollBar.AsNeeded
text: qsTr("In showcase") visible: resolveVisibility(policy, root.height, root.contentHeight)
color: Theme.palette.baseColor1
font.pixelSize: 13
font.weight: Font.Medium
} }
StatusListView { flickable1: EmptyShapeRectangleFooterListView {
id: showcaseItemsListView id: inShowcaseListView
Layout.fillWidth: true
Layout.minimumHeight: Math.floor(targetDropArea.height + targetDropArea.anchors.bottomMargin)
model: showcaseModel
implicitHeight: contentHeight
interactive: false
displaced: Transition { model: root.showcaseModel
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad } width: root.width
placeholderText: root.emptyInShowcasePlaceholderText
placeholderHeight: d.shapeRectangleHeight
header: FoldableHeader {
width: ListView.view.width
title: qsTr("In showcase")
folded: root.flickable1Folded
onToggleFolding: root.flip1Folding()
} }
delegate: DropArea { delegate: DropArea {
@ -154,17 +89,10 @@ Control {
property int visualIndex: index property int visualIndex: index
ListView.onRemove: SequentialAnimation {
PropertyAction { target: showcaseDelegateRoot; property: "ListView.delayRemove"; value: true }
NumberAnimation { target: showcaseDelegateRoot; property: "scale"; to: 0; easing.type: Easing.InOutQuad }
PropertyAction { target: showcaseDelegateRoot; property: "ListView.delayRemove"; value: false }
}
width: ListView.view.width width: ListView.view.width
height: visible && showcaseDraggableDelegateLoader.item ? showcaseDraggableDelegateLoader.item.height : 0 height: visible && showcaseDraggableDelegateLoader.item ? showcaseDraggableDelegateLoader.item.height : 0
keys: ["x-status-draggable-showcase-item"] keys: ["x-status-draggable-showcase-item"]
visible: model.showcaseVisibility !== Constants.ShowcaseVisibility.NoOne visible: model.showcaseVisibility !== Constants.ShowcaseVisibility.NoOne
onEntered: function(drag) { onEntered: function(drag) {
@ -173,10 +101,20 @@ Control {
if (to === from) if (to === from)
return return
root.showcaseEntryChanged() root.showcaseEntryChanged()
showcaseModel.move(from, to, 1) root.showcaseModel.move(from, to, 1)
drag.accept() drag.accept()
} }
// TODO:
// This animation is causing issues when there are no elements in the showcase list.
// Reenable it once the refactor of the models and delegates is done (simplified): #13498
// ListView.onRemove: SequentialAnimation {
// PropertyAction { target: showcaseDelegateRoot; property: "ListView.delayRemove"; value: true }
// NumberAnimation { target: showcaseDelegateRoot; property: "scale"; to: 0; easing.type: Easing.InOutQuad }
// PropertyAction { target: showcaseDelegateRoot; property: "ListView.delayRemove"; value: false }
// }
// In showcase delegate item container:
Loader { Loader {
id: showcaseDraggableDelegateLoader id: showcaseDraggableDelegateLoader
width: parent.width width: parent.width
@ -188,22 +126,15 @@ Control {
} }
} }
// overlaid at the bottom of the listview // TO BE REDEFINED (task #13509): Overlaid at the bottom of the listview
DropArea { DropArea {
id: targetDropArea id: targetDropArea
width: parent.width width: parent.width
height: d.defaultDelegateHeight height: inShowcaseListView.count === 0 ? d.shapeRectangleHeight : d.defaultDelegateHeight
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: showcaseModel.count ? Style.current.halfPadding : 0 anchors.bottomMargin: root.showcaseModel.count ? Style.current.halfPadding : 0
keys: ["x-status-draggable-showcase-item-hidden"] keys: ["x-status-draggable-showcase-item-hidden"]
ShapeRectangle {
anchors.fill: parent
anchors.margins: d.strokeMargin
visible: !showcaseModel.count && !showcaseCombinedDropArea.visible
text: root.hiddenPlaceholderBanner
}
Rectangle { Rectangle {
id: showcaseCombinedDropArea id: showcaseCombinedDropArea
width: parent.width width: parent.width
@ -240,39 +171,31 @@ Control {
} }
} }
StatusBaseText { flickable2: EmptyShapeRectangleFooterListView {
Layout.fillWidth: true id: hiddenListView
Layout.topMargin: Style.current.halfPadding
text: qsTr("Hidden")
color: Theme.palette.baseColor1
font.pixelSize: 13
font.weight: Font.Medium
}
StatusListView {
id: hiddenItemsListView
Layout.fillWidth: true
Layout.minimumHeight: empty ? Math.floor(hiddenTargetDropArea.height + hiddenTargetDropArea.anchors.topMargin)
: d.defaultDelegateHeight * Math.min(count, 4)
implicitHeight: contentHeight
interactive: false
model: root.baseModel model: root.baseModel
width: root.width
placeholderText: root.emptyHiddenPlaceholderText
placeholderHeight: d.shapeRectangleHeight
empty: root.showcaseModel.hiddenCount === 0 && !root.flickable2Folded // TO BE REMOVE: #13498
readonly property bool empty: !contentHeight header: FoldableHeader {
width: ListView.view.width
title: qsTr("Hidden")
folded: root.flickable2Folded
displaced: Transition { onToggleFolding: root.flip2Folding()
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }
} }
delegate: DropArea { delegate: DropArea {
id: delegateRoot id: hiddenDelegateRoot
property int visualIndex: index property int visualIndex: index
visible: root.filterFunc(model) visible: root.filterFunc(model)
width: ListView.view.width width: ListView.view.width
height: visible && draggableDelegateLoader.item ? draggableDelegateLoader.item.height : 0 height: visible && hiddenDraggableDelegateLoader.item ? hiddenDraggableDelegateLoader.item.height : 0
keys: ["x-status-draggable-showcase-item"] keys: ["x-status-draggable-showcase-item"]
@ -281,49 +204,49 @@ Control {
} }
onDropped: function(drop) { onDropped: function(drop) {
root.showcaseModel.setVisibilityByIndex(drop.source.visualIndex, Constants.ShowcaseVisibility.NoOne)
showcaseModel.setVisibilityByIndex(drop.source.visualIndex, Constants.ShowcaseVisibility.NoOne)
root.showcaseEntryChanged() root.showcaseEntryChanged()
} }
// Hidden delegate item container:
Loader {
id: hiddenDraggableDelegateLoader
width: parent.width
sourceComponent: root.hiddenDraggableDelegateComponent
property var modelData: model
property var dragParentData: root
property int visualIndexData: hiddenDelegateRoot.visualIndex
}
// Delegate shadow background when dragging:
Rectangle { Rectangle {
width: parent.width width: parent.width
height: d.defaultDelegateHeight height: d.defaultDelegateHeight
anchors.centerIn: parent anchors.centerIn: parent
color: Theme.palette.baseColor5 color: Theme.palette.baseColor5
radius: Style.current.radius radius: Style.current.radius
visible: draggableDelegateLoader.item && draggableDelegateLoader.item.dragActive visible: hiddenDraggableDelegateLoader.item && hiddenDraggableDelegateLoader.item.dragActive
}
Loader {
id: draggableDelegateLoader
width: parent.width
sourceComponent: root.draggableDelegateComponent
property var modelData: model
property var dragParentData: root
property int visualIndexData: delegateRoot.visualIndex
} }
} }
// overlaid at the top of the listview // TO BE REDEFINED (task #13509): Overlaid at the top of the listview
DropArea { DropArea {
id: hiddenTargetDropArea id: hiddenTargetDropArea
width: parent.width width: root.width
height: d.defaultDelegateHeight height: hiddenListView.empty ? d.shapeRectangleHeight : d.defaultDelegateHeight
anchors.top: parent.top anchors.top: hiddenListView.top
anchors.topMargin: !hiddenItemsListView.empty ? Style.current.halfPadding : 0 anchors.topMargin: hiddenListView.empty ? hiddenListView.headerItem.height : hiddenListView.headerItem.height + Style.current.halfPadding
keys: ["x-status-draggable-showcase-item"] keys: ["x-status-draggable-showcase-item"]
ShapeRectangle { ShapeRectangle {
readonly property bool stroked: hiddenItemsListView.empty && !parent.containsDrag width: parent.width
height: parent.height + d.strokeMargin
anchors.fill: parent anchors.centerIn: parent
anchors.margins: d.strokeMargin visible: parent.containsDrag
visible: hiddenItemsListView.empty || parent.containsDrag path.fillColor: Theme.palette.baseColor5
path.fillColor: stroked ? "transparent" : Theme.palette.baseColor5 path.strokeColor: "transparent"
path.strokeColor: stroked ? Theme.palette.baseColor2 : "transparent" text: root.emptyHiddenPlaceholderText
text: root.showcasePlaceholderBanner
} }
onEntered: function(drag) { onEntered: function(drag) {
@ -331,20 +254,76 @@ Control {
} }
onDropped: function(drop) { onDropped: function(drop) {
showcaseModel.setVisibilityByIndex(drop.source.visualIndex, Constants.ShowcaseVisibility.NoOne) root.showcaseModel.setVisibilityByIndex(drop.source.visualIndex, Constants.ShowcaseVisibility.NoOne)
root.showcaseEntryChanged() root.showcaseEntryChanged()
root.updateBaseModelFilters() root.updateBaseModelFilters()
} }
} }
} }
Loader { // TO BE REDEFINED (task #13509)
id: additionalComponent component VisibilityDropArea: AbstractButton {
id: visibilityDropAreaLocal
property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne
readonly property alias containsDrag: dropArea.containsDrag
padding: Style.current.halfPadding
spacing: padding/2
icon.color: Theme.palette.primaryColor1
background: ShapeRectangle {
path.strokeColor: dropArea.containsDrag ? "transparent" : Theme.palette.directColor7
path.fillColor: dropArea.containsDrag ? Theme.palette.white : "transparent"
DropArea {
id: dropArea
anchors.fill: parent
keys: ["x-status-draggable-showcase-item-hidden"]
onEntered: function(drag) {
drag.accept()
}
onDropped: function(drop) {
var showcaseObj = drop.source.showcaseObj
// need to set total balance for an asset
if (drop.source.totalValue !== undefined) {
showcaseObj.enabledNetworkBalance = drop.source.totalValue
}
var tmpObj = Object()
root.roleNames.forEach(role => tmpObj[role] = showcaseObj[role])
tmpObj.showcaseVisibility = visibilityDropAreaLocal.showcaseVisibility
root.showcaseModel.upsertItemJson(JSON.stringify(tmpObj))
root.showcaseEntryChanged()
}
}
}
contentItem: Item {
RowLayout {
width: Math.min(parent.width, implicitWidth)
anchors.centerIn: parent
spacing: visibilityDropAreaLocal.spacing
StatusIcon {
width: 20
height: width
icon: ProfileUtils.visibilityIcon(visibilityDropAreaLocal.showcaseVisibility)
color: visibilityDropAreaLocal.icon.color
}
StatusBaseText {
Layout.fillWidth: true Layout.fillWidth: true
sourceComponent: root.additionalComponent font.pixelSize: 13
} font.weight: Font.Medium
elide: Text.ElideRight
Item { Layout.fillHeight: true } color: visibilityDropAreaLocal.icon.color
text: visibilityDropAreaLocal.text
}
}
}
} }
} }

View File

@ -66,7 +66,7 @@ Shape {
id: description id: description
color: root.textColor color: root.textColor
text: root.text text: root.text
font.pixelSize: 13 font.pixelSize: Style.current.additionalTextSize
visible: !!text visible: !!text
} }
} }