chore(@desktop/wallet): Use transparent background and add scroll shadow (#11118)

This commit is contained in:
Cuteivist 2023-06-16 11:37:17 +02:00 committed by GitHub
parent 47c76714db
commit 5d7a4723bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 115 additions and 94 deletions

View File

@ -575,9 +575,11 @@ Item {
width: parent.width width: parent.width
height: detailsColumn.childrenRect.height height: detailsColumn.childrenRect.height
default property alias content: detailsColumn.children default property alias content: detailsColumn.children
Rectangle { Rectangle {
id: tileBackground id: tileBackground
anchors.fill: parent anchors.fill: parent
color: Style.current.transparent
radius: 8 radius: 8
border.width: 1 border.width: 1
border.color: Style.current.separator border.color: Style.current.separator
@ -590,7 +592,12 @@ Item {
spacing: 0 spacing: 0
layer.enabled: true layer.enabled: true
layer.effect: OpacityMask { layer.effect: OpacityMask {
maskSource: tileBackground // Separate rectangle is used as mask because background rectangle must be transaprent
maskSource: Rectangle {
width: tileBackground.width
height: tileBackground.height
radius: tileBackground.radius
}
} }
} }
} }

View File

@ -5,6 +5,7 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import utils 1.0
import shared.panels 1.0 import shared.panels 1.0
/*! /*!
@ -61,6 +62,7 @@ StatusListItem {
height: visible ? implicitHeight + bottomPadding : 0 height: visible ? implicitHeight + bottomPadding : 0
radius: 0 radius: 0
sensor.cursorShape: Qt.ArrowCursor sensor.cursorShape: Qt.ArrowCursor
color: sensor.containsMouse ? Theme.palette.baseColor5 : Style.current.transparent
// Title // Title
statusListItemTitle.customColor: Theme.palette.directColor5 statusListItemTitle.customColor: Theme.palette.directColor5

View File

@ -399,7 +399,7 @@ StatusListItem {
rightPadding: 16 rightPadding: 16
enabled: !loading enabled: !loading
color: sensor.containsMouse ? Theme.palette.baseColor5 : Theme.palette.statusListItem.backgroundColor color: sensor.containsMouse ? Theme.palette.baseColor5 : Style.current.transparent
statusListItemIcon.active: (loading || root.asset.name) statusListItemIcon.active: (loading || root.asset.name)
asset { asset {

View File

@ -74,129 +74,141 @@ ColumnLayout {
store: WalletStores.RootStore store: WalletStores.RootStore
} }
Separator { Item {
Layout.fillWidth: true
visible: filterComponent.visible
}
StatusListView {
id: transactionListRoot
objectName: "walletAccountTransactionList"
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
Layout.topMargin: nonArchivalNodeError.visible || noTxs.visible ? Style.current.padding : 0 Layout.topMargin: nonArchivalNodeError.visible || noTxs.visible ? Style.current.padding : 0
Layout.bottomMargin: Style.current.padding Layout.bottomMargin: Style.current.padding
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
property string firstSection Rectangle { // Shadow behind delegates when scrolling
anchors.top: topListSeparator.bottom
width: parent.width
height: 4
color: Style.current.separator
visible: topListSeparator.visible
}
model: SortFilterProxyModel { StatusListView {
id: txModel id: transactionListRoot
objectName: "walletAccountTransactionList"
anchors.fill: parent
sourceModel: RootStore.historyTransactions property string firstSection
// LocaleUtils is not accessable from inside expression, but local function works model: SortFilterProxyModel {
property var formatDate: (ms) => LocaleUtils.formatDate(ms, Locale.ShortFormat) id: txModel
proxyRoles: ExpressionRole {
name: "date" sourceModel: RootStore.historyTransactions
expression: {
return model.activityEntry.timestamp > 0 ? txModel.formatDate(model.activityEntry.timestamp * 1000) : (d.isLoading ? " " : "") // not empty, because section will not be displayed when loading if empty // LocaleUtils is not accessable from inside expression, but local function works
property var formatDate: (ms) => LocaleUtils.formatDate(ms, Locale.ShortFormat)
proxyRoles: ExpressionRole {
name: "date"
expression: {
return model.activityEntry.timestamp > 0 ? txModel.formatDate(model.activityEntry.timestamp * 1000) : (d.isLoading ? " " : "") // not empty, because section will not be displayed when loading if empty
}
} }
} }
}
delegate: transactionDelegate delegate: transactionDelegate
footer: footerComp footer: footerComp
displaced: Transition { // TODO Remove animation when ordered fetching of transactions is implemented displaced: Transition { // TODO Remove animation when ordered fetching of transactions is implemented
NumberAnimation { properties: "y"; duration: 250; easing.type: Easing.Linear; alwaysRunToEnd: true } NumberAnimation { properties: "y"; duration: 250; easing.type: Easing.Linear; alwaysRunToEnd: true }
} }
readonly property point lastVisibleItemPos: Qt.point(0, contentY + height - 1) readonly property point lastVisibleItemPos: Qt.point(0, contentY + height - 1)
property int lastVisibleIndex: indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y) property int lastVisibleIndex: indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y)
onCountChanged: {
// Preserve last visible item in view when more items added at the end or
// inbetween
// TODO Remove this logic, when new activity design is implemented
// and items are loaded in order
const lastVisibleItem = itemAtIndex(lastVisibleIndex)
const newItem = itemAt(lastVisibleItemPos.x, lastVisibleItemPos.y)
const lastVisibleItemY = lastVisibleItem ? lastVisibleItem.y : -1
if (newItem) {
if (newItem.y < lastVisibleItemY) { // item inserted higher than last visible
lastVisibleIndex = indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y)
}
}
}
currentIndex: 0
property bool userScrolled: false
onCountChanged: {
// Preserve last visible item in view when more items added at the end or
// inbetween
// TODO Remove this logic, when new activity design is implemented // TODO Remove this logic, when new activity design is implemented
// and items are loaded in order // and items are loaded in order
const lastVisibleItem = itemAtIndex(lastVisibleIndex) onMovingVerticallyChanged: {
const newItem = itemAt(lastVisibleItemPos.x, lastVisibleItemPos.y) if (!userScrolled) {
const lastVisibleItemY = lastVisibleItem ? lastVisibleItem.y : -1 userScrolled = true
if (newItem) { currentIndex = Qt.binding(() => lastVisibleIndex >= 0 ? lastVisibleIndex : (count - 1))
if (newItem.y < lastVisibleItemY) { // item inserted higher than last visible
lastVisibleIndex = indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y)
} }
}
}
currentIndex: 0
property bool userScrolled: false lastVisibleIndex = indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y)
// TODO Remove this logic, when new activity design is implemented
// and items are loaded in order
onMovingVerticallyChanged: {
if (!userScrolled) {
userScrolled = true
currentIndex = Qt.binding(() => lastVisibleIndex >= 0 ? lastVisibleIndex : (count - 1))
} }
lastVisibleIndex = indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y) ScrollBar.vertical: StatusScrollBar {}
}
ScrollBar.vertical: StatusScrollBar {} section.property: "date"
topMargin: -20 // Top margin for first section. Section cannot have different sizes
section.delegate: ColumnLayout {
id: sectionDelegate
section.property: "date" readonly property bool isFirstSection: ListView.view.firstSection === section
topMargin: -20 // Top margin for first section. Section cannot have different sizes
section.delegate: ColumnLayout {
id: sectionDelegate
readonly property bool isFirstSection: ListView.view.firstSection === section width: ListView.view.width
// display always first section. Other sections when more items are being fetched must not be visible
// 1 because we don't use empty for loading state
// Additionaly height must be defined so all sections use same height to to glitch sections when updating model
height: isFirstSection || section.length > 1 ? 58 : 0
visible: height > 0 // display always first section. Other sections when more items are being fetched must not be visible
spacing: 0
width: ListView.view.width required property string section
// display always first section. Other sections when more items are being fetched must not be visible
// 1 because we don't use empty for loading state
// Additionaly height must be defined so all sections use same height to to glitch sections when updating model
height: isFirstSection || section.length > 1 ? 58 : 0
visible: height > 0 // display always first section. Other sections when more items are being fetched must not be visible
spacing: 0
required property string section Separator {
Layout.fillWidth: true
Separator { Layout.topMargin: 20
Layout.fillWidth: true implicitHeight: 1
Layout.topMargin: 20
implicitHeight: 1
visible: !sectionDelegate.isFirstSection
}
StatusTextWithLoadingState {
id: sectionText
Layout.alignment: Qt.AlignBottom
leftPadding: 16
bottomPadding: 8
text: loading ? "dummy" : parent.section // dummy text because loading component height depends on text height, and not visible with height == 0
Binding on width {
when: sectionText.loading
value: 56
restoreMode: Binding.RestoreBindingOrValue
} }
customColor: Theme.palette.baseColor1
font.pixelSize: 13 StatusTextWithLoadingState {
verticalAlignment: Qt.AlignBottom id: sectionText
loading: { // First section must be loading when first item in the list is loading. Other sections are never visible until have date value Layout.alignment: Qt.AlignBottom
if (parent.ListView.view.count > 0) { leftPadding: 16
const firstItem = parent.ListView.view.itemAtIndex(0) bottomPadding: 8
if (sectionDelegate.isFirstSection && firstItem && firstItem.loading) { text: loading ? "dummy" : parent.section // dummy text because loading component height depends on text height, and not visible with height == 0
return true Binding on width {
} when: sectionText.loading
value: 56
restoreMode: Binding.RestoreBindingOrValue
}
customColor: Theme.palette.baseColor1
font.pixelSize: 13
verticalAlignment: Qt.AlignBottom
loading: { // First section must be loading when first item in the list is loading. Other sections are never visible until have date value
if (parent.ListView.view.count > 0) {
const firstItem = parent.ListView.view.itemAtIndex(0)
if (sectionDelegate.isFirstSection && firstItem && firstItem.loading) {
return true
}
}
return false
} }
return false
} }
} }
onAtYEndChanged: if(atYEnd) RootStore.fetchMoreTransactions()
}
Separator {
id: topListSeparator
width: parent.width
visible: !transactionListRoot.atYBeginning
} }
onAtYEndChanged: if(atYEnd) RootStore.fetchMoreTransactions()
} }
StatusMenu { StatusMenu {