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
height: detailsColumn.childrenRect.height
default property alias content: detailsColumn.children
Rectangle {
id: tileBackground
anchors.fill: parent
color: Style.current.transparent
radius: 8
border.width: 1
border.color: Style.current.separator
@ -590,7 +592,12 @@ Item {
spacing: 0
layer.enabled: true
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.Controls 0.1
import utils 1.0
import shared.panels 1.0
/*!
@ -61,6 +62,7 @@ StatusListItem {
height: visible ? implicitHeight + bottomPadding : 0
radius: 0
sensor.cursorShape: Qt.ArrowCursor
color: sensor.containsMouse ? Theme.palette.baseColor5 : Style.current.transparent
// Title
statusListItemTitle.customColor: Theme.palette.directColor5

View File

@ -399,7 +399,7 @@ StatusListItem {
rightPadding: 16
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)
asset {

View File

@ -74,129 +74,141 @@ ColumnLayout {
store: WalletStores.RootStore
}
Separator {
Layout.fillWidth: true
visible: filterComponent.visible
}
StatusListView {
id: transactionListRoot
objectName: "walletAccountTransactionList"
Item {
Layout.alignment: Qt.AlignTop
Layout.topMargin: nonArchivalNodeError.visible || noTxs.visible ? Style.current.padding : 0
Layout.bottomMargin: Style.current.padding
Layout.bottomMargin: Style.current.padding
Layout.fillWidth: 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 {
id: txModel
StatusListView {
id: transactionListRoot
objectName: "walletAccountTransactionList"
anchors.fill: parent
sourceModel: RootStore.historyTransactions
property string firstSection
// 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
model: SortFilterProxyModel {
id: txModel
sourceModel: RootStore.historyTransactions
// 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
NumberAnimation { properties: "y"; duration: 250; easing.type: Easing.Linear; alwaysRunToEnd: true }
}
displaced: Transition { // TODO Remove animation when ordered fetching of transactions is implemented
NumberAnimation { properties: "y"; duration: 250; easing.type: Easing.Linear; alwaysRunToEnd: true }
}
readonly property point lastVisibleItemPos: Qt.point(0, contentY + height - 1)
property int lastVisibleIndex: indexAt(lastVisibleItemPos.x, lastVisibleItemPos.y)
readonly property point lastVisibleItemPos: Qt.point(0, contentY + height - 1)
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
// 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)
onMovingVerticallyChanged: {
if (!userScrolled) {
userScrolled = true
currentIndex = Qt.binding(() => lastVisibleIndex >= 0 ? lastVisibleIndex : (count - 1))
}
}
}
currentIndex: 0
property bool userScrolled: false
// 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)
}
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"
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
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
// 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
required property string section
Separator {
Layout.fillWidth: true
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
Separator {
Layout.fillWidth: true
Layout.topMargin: 20
implicitHeight: 1
}
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
}
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
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 {