feat(ProfileShowcase): Drop area behaviour / design when sections expanded

- It updates `ProfileShowcasePanel` with new drop area design adding shadows, changing drop areas design and sizes.

- It adjusts `ShowcaseDelegate` according to design, ie: heigh and background colour on dragActive.

Closes #13509
This commit is contained in:
Noelia 2024-02-23 08:14:55 +01:00 committed by Noelia
parent 1af5c166c5
commit 1dc03624d6
4 changed files with 194 additions and 112 deletions

View File

@ -26,6 +26,12 @@ StatusDraggableListItem {
icon.color: Theme.palette.primaryColor1 icon.color: Theme.palette.primaryColor1
} }
height: ProfileUtils.defaultDelegateHeight
topInset: 0
bottomInset: 0
changeColorOnDragActive: false
bgColor: Theme.palette.getColor(Theme.palette.statusAppLayout.rightPanelBackgroundColor, 0.7)
icon.width: 40 icon.width: 40
icon.height: 40 icon.height: 40

View File

@ -57,10 +57,11 @@ DoubleFlickableWithFolding {
QtObject { QtObject {
id: d id: d
readonly property int defaultDelegateHeight: 60 readonly property var dragHiddenItemKey: ["x-status-draggable-showcase-item-hidden"]
readonly property int contentSpacing: 12 readonly property var dragShowcaseItemKey: ["x-status-draggable-showcase-item"]
readonly property int strokeMargin: 2
readonly property int shapeRectangleHeight: 48 property bool isAnyShowcaseDragActive: false
property bool isAnyHiddenDragActive: false
} }
clip: true clip: true
@ -76,7 +77,9 @@ DoubleFlickableWithFolding {
model: root.showcaseModel model: root.showcaseModel
width: root.width width: root.width
placeholderText: root.emptyInShowcasePlaceholderText placeholderText: root.emptyInShowcasePlaceholderText
placeholderHeight: d.shapeRectangleHeight footerHeight: ProfileUtils.defaultDelegateHeight
footerContentVisible: !dropAreaRow.visible
spacing: Style.current.halfPadding
header: FoldableHeader { header: FoldableHeader {
width: ListView.view.width width: ListView.view.width
@ -94,7 +97,7 @@ DoubleFlickableWithFolding {
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: d.dragShowcaseItemKey
visible: model.showcaseVisibility !== Constants.ShowcaseVisibility.NoOne visible: model.showcaseVisibility !== Constants.ShowcaseVisibility.NoOne
onEntered: function(drag) { onEntered: function(drag) {
@ -119,56 +122,44 @@ DoubleFlickableWithFolding {
// In showcase delegate item container: // In showcase delegate item container:
Loader { Loader {
id: showcaseDraggableDelegateLoader id: showcaseDraggableDelegateLoader
width: parent.width
sourceComponent: root.showcaseDraggableDelegateComponent
property var modelData: model property var modelData: model
property var dragParentData: root property var dragParentData: root
property int visualIndexData: index property int visualIndexData: index
width: parent.width
sourceComponent: !dropAreaRow.visible ? root.showcaseDraggableDelegateComponent : emptyDelegate // TODO: Blur delegate issue ##13594
}
// Delegate shadow background when dragging:
ShadowDelegate {
id: showcaseShadow
visible: showcaseDraggableDelegateLoader.item && showcaseDraggableDelegateLoader.item.dragActive
onVisibleChanged: d.isAnyShowcaseDragActive = visible
} }
} }
// TO BE REDEFINED (task #13509): Overlaid at the bottom of the listview // Overlaid showcase listview content drop area:
DropArea { DropArea {
id: targetDropArea
width: parent.width
height: inShowcaseListView.count === 0 ? d.shapeRectangleHeight : d.defaultDelegateHeight
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: root.showcaseModel.count ? Style.current.halfPadding : 0
keys: ["x-status-draggable-showcase-item-hidden"]
Rectangle {
id: showcaseCombinedDropArea
width: parent.width width: parent.width
height: parent.height + d.strokeMargin height: parent.contentHeight
anchors.centerIn: parent keys: d.dragHiddenItemKey
color: Theme.palette.baseColor5
radius: Style.current.radius
visible: parent.containsDrag || dropAreaEveryone.containsDrag || dropAreaContacts.containsDrag || dropAreaVerified.containsDrag
RowLayout { // Shown at the bottom of the listview
width: parent.width - spacing*2 VisibilityDropAreaButtonsRow {
anchors.centerIn: parent id: dropAreaRow
spacing: d.contentSpacing
VisibilityDropArea { width: parent.width
id: dropAreaEveryone height: ProfileUtils.defaultDelegateHeight
Layout.fillWidth: true anchors.bottom: parent.bottom
showcaseVisibility: Constants.ShowcaseVisibility.Everyone
text: qsTr("Everyone") visible: d.isAnyHiddenDragActive ||
} parent.containsDrag ||
VisibilityDropArea { everyoneContainsDrag ||
id: dropAreaContacts contactsContainsDrag ||
Layout.fillWidth: true verifiedContainsDrag
showcaseVisibility: Constants.ShowcaseVisibility.Contacts
text: qsTr("Contacts")
}
VisibilityDropArea {
id: dropAreaVerified
Layout.fillWidth: true
showcaseVisibility: Constants.ShowcaseVisibility.IdVerifiedContacts
text: qsTr("Verified")
}
}
} }
} }
} }
@ -179,9 +170,11 @@ DoubleFlickableWithFolding {
model: root.baseModel model: root.baseModel
width: root.width width: root.width
placeholderText: root.emptyHiddenPlaceholderText placeholderText: root.emptyHiddenPlaceholderText
placeholderHeight: d.shapeRectangleHeight footerHeight: ProfileUtils.defaultDelegateHeight
footerContentVisible: !hiddenDropAreaButton.visible
empty: root.showcaseModel.hiddenCount === 0 && !root.flickable2Folded // TO BE REMOVE: #13498 empty: root.showcaseModel.hiddenCount === 0 && !root.flickable2Folded // TO BE REMOVE: #13498
additionalFooterComponent: root.additionalFooterComponent additionalFooterComponent: root.additionalFooterComponent
spacing: Style.current.halfPadding
header: FoldableHeader { header: FoldableHeader {
width: ListView.view.width width: ListView.view.width
@ -200,7 +193,7 @@ DoubleFlickableWithFolding {
width: ListView.view.width width: ListView.view.width
height: visible && hiddenDraggableDelegateLoader.item ? hiddenDraggableDelegateLoader.item.height : 0 height: visible && hiddenDraggableDelegateLoader.item ? hiddenDraggableDelegateLoader.item.height : 0
keys: ["x-status-draggable-showcase-item"] keys: d.dragShowcaseItemKey
onEntered: function(drag) { onEntered: function(drag) {
drag.accept() drag.accept()
@ -214,62 +207,63 @@ DoubleFlickableWithFolding {
// Hidden delegate item container: // Hidden delegate item container:
Loader { Loader {
id: hiddenDraggableDelegateLoader id: hiddenDraggableDelegateLoader
width: parent.width
sourceComponent: root.hiddenDraggableDelegateComponent
property var modelData: model property var modelData: model
property var dragParentData: root property var dragParentData: root
property int visualIndexData: hiddenDelegateRoot.visualIndex property int visualIndexData: hiddenDelegateRoot.visualIndex
width: parent.width
sourceComponent: !hiddenDropAreaButton.visible ? root.hiddenDraggableDelegateComponent : emptyDelegate // TODO: Blur delegate issue ##13594
} }
// Delegate shadow background when dragging: // Delegate shadow background when dragging:
Rectangle { ShadowDelegate {
width: parent.width id: hiddenShadow
height: d.defaultDelegateHeight
anchors.centerIn: parent
color: Theme.palette.baseColor5
radius: Style.current.radius
visible: hiddenDraggableDelegateLoader.item && hiddenDraggableDelegateLoader.item.dragActive visible: hiddenDraggableDelegateLoader.item && hiddenDraggableDelegateLoader.item.dragActive
onVisibleChanged: d.isAnyHiddenDragActive = visible
} }
} }
// TO BE REDEFINED (task #13509): Overlaid at the top of the listview // Overlaid hidden listview content drop area:
DropArea { DropArea {
id: hiddenTargetDropArea anchors.top: parent.top
width: root.width
height: hiddenListView.empty ? d.shapeRectangleHeight : d.defaultDelegateHeight
anchors.top: hiddenListView.top
anchors.topMargin: hiddenListView.empty ? hiddenListView.headerItem.height : hiddenListView.headerItem.height + Style.current.halfPadding
keys: ["x-status-draggable-showcase-item"]
ShapeRectangle {
width: parent.width width: parent.width
height: parent.height + d.strokeMargin height: parent.contentHeight
anchors.centerIn: parent keys: d.dragShowcaseItemKey
visible: parent.containsDrag
path.fillColor: Theme.palette.baseColor5
path.strokeColor: "transparent"
text: root.emptyHiddenPlaceholderText
}
onEntered: function(drag) { // Shown at the top of the listview
drag.accept() VisibilityDropAreaButton {
} id: hiddenDropAreaButton
onDropped: function(drop) { anchors.top: parent.top
root.showcaseModel.setVisibilityByIndex(drop.source.visualIndex, Constants.ShowcaseVisibility.NoOne) anchors.topMargin: hiddenListView.headerItem.height + Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
visible: d.isAnyShowcaseDragActive || parent.containsDrag || hiddenDropAreaButton.containsDrag
width: parent.width - Style.current.padding
height: ProfileUtils.defaultDelegateHeight - Style.current.padding
text: qsTr("Hide")
dropAreaKeys: d.dragShowcaseItemKey
onDropped: {
root.showcaseModel.setVisibilityByIndex(drop.source.visualIndex, visibility)
root.showcaseEntryChanged() root.showcaseEntryChanged()
root.updateBaseModelFilters() root.updateBaseModelFilters()
} }
} }
} }
}
// TO BE REDEFINED (task #13509) component VisibilityDropAreaButton: AbstractButton {
component VisibilityDropArea: AbstractButton { id: visibilityDropAreaButton
id: visibilityDropAreaLocal
readonly property alias containsDrag: dropArea.containsDrag
property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne
readonly property alias containsDrag: dropArea.containsDrag property var dropAreaKeys
signal dropped(var drop, int visibility)
padding: Style.current.halfPadding padding: Style.current.halfPadding
spacing: padding/2 spacing: padding/2
@ -277,18 +271,58 @@ DoubleFlickableWithFolding {
icon.color: Theme.palette.primaryColor1 icon.color: Theme.palette.primaryColor1
background: ShapeRectangle { background: ShapeRectangle {
path.strokeColor: dropArea.containsDrag ? "transparent" : Theme.palette.directColor7 path.strokeColor: dropArea.containsDrag ? Theme.palette.primaryColor2 : Theme.palette.directColor7
path.fillColor: dropArea.containsDrag ? Theme.palette.white : "transparent" path.fillColor: dropArea.containsDrag ? Theme.palette.primaryColor3 : Theme.palette.baseColor4
DropArea { DropArea {
id: dropArea id: dropArea
anchors.fill: parent anchors.fill: parent
keys: ["x-status-draggable-showcase-item-hidden"] keys: visibilityDropAreaButton.dropAreaKeys
onEntered: function(drag) { onEntered: function(drag) {
drag.accept() drag.accept()
} }
onDropped: function(drop) { onDropped: function(drop) {
visibilityDropAreaButton.dropped(drop, visibilityDropAreaButton.showcaseVisibility)
}
}
}
contentItem: Item {
RowLayout {
width: Math.min(parent.width, implicitWidth)
anchors.centerIn: parent
spacing: visibilityDropAreaButton.spacing
StatusIcon {
width: 20
height: width
icon: ProfileUtils.visibilityIcon(visibilityDropAreaButton.showcaseVisibility)
color: visibilityDropAreaButton.icon.color
}
StatusBaseText {
Layout.fillWidth: true
font.pixelSize: Style.current.additionalTextSize
font.weight: Font.Medium
elide: Text.ElideRight
color: visibilityDropAreaButton.icon.color
text: visibilityDropAreaButton.text
}
}
}
}
component VisibilityDropAreaButtonsRow: Item {
id: visibilityDropAreaRow
readonly property bool everyoneContainsDrag: dropAreaEveryone.containsDrag
readonly property bool contactsContainsDrag: dropAreaContacts.containsDrag
readonly property bool verifiedContainsDrag: dropAreaVerified.containsDrag
function dropped(drop, visibility) {
var showcaseObj = drop.source.showcaseObj var showcaseObj = drop.source.showcaseObj
// need to set total balance for an asset // need to set total balance for an asset
@ -298,35 +332,68 @@ DoubleFlickableWithFolding {
var tmpObj = Object() var tmpObj = Object()
root.roleNames.forEach(role => tmpObj[role] = showcaseObj[role]) root.roleNames.forEach(role => tmpObj[role] = showcaseObj[role])
tmpObj.showcaseVisibility = visibilityDropAreaLocal.showcaseVisibility tmpObj.showcaseVisibility = visibility
root.showcaseModel.upsertItemJson(JSON.stringify(tmpObj)) root.showcaseModel.upsertItemJson(JSON.stringify(tmpObj))
root.showcaseEntryChanged() root.showcaseEntryChanged()
} }
}
}
contentItem: Item {
RowLayout { RowLayout {
width: Math.min(parent.width, implicitWidth) anchors.fill: parent
anchors.centerIn: parent anchors.margins: Style.current.halfPadding
spacing: visibilityDropAreaLocal.spacing spacing: Style.current.halfPadding
StatusIcon { VisibilityDropAreaButton {
width: 20 id: dropAreaEveryone
height: width
icon: ProfileUtils.visibilityIcon(visibilityDropAreaLocal.showcaseVisibility)
color: visibilityDropAreaLocal.icon.color
}
StatusBaseText {
Layout.fillWidth: true Layout.fillWidth: true
font.pixelSize: 13 Layout.fillHeight: true
font.weight: Font.Medium showcaseVisibility: Constants.ShowcaseVisibility.Everyone
elide: Text.ElideRight text: qsTr("Everyone")
color: visibilityDropAreaLocal.icon.color dropAreaKeys: d.dragHiddenItemKey
text: visibilityDropAreaLocal.text
onDropped: visibilityDropAreaRow.dropped(drop, visibility)
}
VisibilityDropAreaButton {
id: dropAreaContacts
Layout.fillWidth: true
Layout.fillHeight: true
showcaseVisibility: Constants.ShowcaseVisibility.Contacts
text: qsTr("Contacts")
dropAreaKeys: d.dragHiddenItemKey
onDropped: visibilityDropAreaRow.dropped(drop, visibility)
}
VisibilityDropAreaButton {
id: dropAreaVerified
Layout.fillWidth: true
Layout.fillHeight: true
showcaseVisibility: Constants.ShowcaseVisibility.IdVerifiedContacts
text: qsTr("Verified")
dropAreaKeys: d.dragHiddenItemKey
onDropped: visibilityDropAreaRow.dropped(drop, visibility)
} }
} }
} }
component ShadowDelegate: Rectangle {
width: parent.width
height: ProfileUtils.defaultDelegateHeight
anchors.centerIn: parent
color: Theme.palette.baseColor5
radius: Style.current.radius
}
// TODO: Blur delegate issue ##13594
Component {
id: emptyDelegate
Item {
property bool dragActive: false
width: parent.width
height: ProfileUtils.defaultDelegateHeight
}
} }
} }

View File

@ -11,7 +11,8 @@ StatusListView {
id: root id: root
property string placeholderText property string placeholderText
property int placeholderHeight: 44 property int footerHeight: 44
property bool footerContentVisible: true
property Component additionalFooterComponent property Component additionalFooterComponent
// TO BE REMOVE: #13498 // TO BE REMOVE: #13498
@ -22,17 +23,22 @@ StatusListView {
footer: ColumnLayout { footer: ColumnLayout {
width: root.width width: root.width
Item {
Layout.preferredHeight: root.footerHeight
Layout.fillWidth: true
visible: root.empty// TO BE REPLACE root.empty in (#13498): root.empty = root.model && root.count === 0
ShapeRectangle { ShapeRectangle {
id: shapeRectangle id: shapeRectangle
Layout.preferredHeight: root.placeholderHeight anchors.fill: parent
Layout.fillWidth: true anchors.margins: 1
Layout.alignment: Qt.AlignHCenter
Layout.margins: 1
visible: root.empty// TO BE REPLACE by (#13498): root.model && root.count === 0 visible: root.footerContentVisible
text: root.placeholderText text: root.placeholderText
} }
}
Loader { Loader {
Layout.preferredWidth: root.width Layout.preferredWidth: root.width

View File

@ -5,6 +5,9 @@ import QtQml 2.14
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
QtObject { QtObject {
readonly property int defaultDelegateHeight: 76
function displayName(nickName, ensName, displayName, aliasName) function displayName(nickName, ensName, displayName, aliasName)
{ {
return nickName || ensName || displayName || aliasName return nickName || ensName || displayName || aliasName