fix(@desktop/activity): Fix filter layout and added recipient search (#11883)

This commit is contained in:
Cuteivist 2023-08-16 16:06:56 +02:00 committed by GitHub
parent dc950d828f
commit beaca31664
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 309 additions and 236 deletions

View File

@ -64,6 +64,11 @@ Item {
This property holds a reference to the TextEdit's placeholderText property. This property holds a reference to the TextEdit's placeholderText property.
*/ */
property alias placeholderText: statusBaseInput.placeholderText property alias placeholderText: statusBaseInput.placeholderText
/*!
\qmlproperty alias StatusInput::placeholderFont
This property holds a reference to the TextEdit's placeholder font property.
*/
property alias placeholderFont: statusBaseInput.placeholderFont
/*! /*!
\qmlproperty alias StatusInput::font \qmlproperty alias StatusInput::font
This property holds a reference to the TextEdit's font property. This property holds a reference to the TextEdit's font property.

View File

@ -97,12 +97,12 @@ Item {
id: leftTab id: leftTab
anchors.fill: parent anchors.fill: parent
changeSelectedAccount: function(address) { changeSelectedAccount: function(address) {
RootStore.setFilterAddress(address)
root.resetView() root.resetView()
RootStore.setFilterAddress(address)
} }
selectAllAccounts: function() { selectAllAccounts: function() {
RootStore.setFillterAllAddresses()
root.resetView() root.resetView()
RootStore.setFillterAllAddresses()
} }
onShowSavedAddressesChanged: { onShowSavedAddressesChanged: {
if(showSavedAddresses) if(showSavedAddresses)

View File

@ -84,7 +84,7 @@ StatusMenu {
} }
ActivityTokensFilterSubMenu { ActivityTokensFilterSubMenu {
id: tokensMenu id: tokensMenu
height: Math.min(439, tokensMenu.implicitHeight) height: 439
onBack: root.open() onBack: root.open()
tokensList: root.tokensList tokensList: root.tokensList
tokensFilter: root.tokensFilter tokensFilter: root.tokensFilter
@ -96,7 +96,7 @@ StatusMenu {
} }
ActivityCounterpartyFilterSubMenu { ActivityCounterpartyFilterSubMenu {
id: counterPartyMenu id: counterPartyMenu
height: Math.min(439, counterPartyMenu.implicitHeight) height: 439
onBack: root.open() onBack: root.open()
store: root.store store: root.store
recentsList: root.recentsList recentsList: root.recentsList

View File

@ -40,124 +40,183 @@ StatusMenu {
Component.onCompleted: root.updateRecipientsModel() Component.onCompleted: root.updateRecipientsModel()
MenuBackButton { contentItem: ColumnLayout {
id: backButton spacing: 12
width: parent.width
onClicked: {
close()
back()
}
}
StatusSwitchTabBar { MenuBackButton {
id: tabBar id: backButton
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: backButton.bottom
anchors.topMargin: 12
width: parent.width - 16
StatusSwitchTabButton {
text: qsTr("Recent")
}
StatusSwitchTabButton {
text: qsTr("Saved")
}
}
StackLayout {
id: layout
width: parent.width
anchors.top: tabBar.bottom
anchors.topMargin: 12
currentIndex: tabBar.currentIndex
Column {
id: column1
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 onClicked: {
ButtonGroup { close()
id: recentsButtonGroup back()
exclusive: false
} }
StatusBaseText { }
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("No Recents") SearchBox {
visible: root.recentsList.count === 0 && !root.loadingRecipients id: searchBox
property string searchValue: ""
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: 8
Layout.rightMargin: 8
font.pixelSize: 13
placeholderFont.pixelSize: font.pixelSize
input.height: 36
placeholderText: qsTr("Search name, ENS or address")
onTextChanged: searchTimer.restart()
// Used to optimize the search when writing word
Timer {
id: searchTimer
interval: 750
onTriggered: searchBox.searchValue = searchBox.text
} }
StatusBaseText { }
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Loading Recents") StatusSwitchTabBar {
visible: root.loadingRecipients id: tabBar
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: 8
Layout.rightMargin: 8
StatusSwitchTabButton {
text: qsTr("Recent")
} }
StatusListView { StatusSwitchTabButton {
visible: !root.loadingRecipients text: qsTr("Saved")
width: parent.width }
height: root.height - tabBar.height - 12 }
model: root.recentsList
reuseItems: true StackLayout {
delegate: ActivityTypeCheckBox { id: layout
readonly property string name: store.getNameForAddress(model.address) Layout.fillWidth: true
width: ListView.view.width Layout.fillHeight: true
height: 44 currentIndex: tabBar.currentIndex
title: name || StatusQUtils.Utils.elideText(model.address,6,4)
subTitle: name ? StatusQUtils.Utils.elideText(model.address,6,4): "" ColumnLayout {
statusListItemSubTitle.elide: Text.ElideMiddle id: column1
statusListItemSubTitle.wrapMode: Text.NoWrap Layout.fillWidth: true
assetSettings.name: name || "address" Layout.fillHeight: true
assetSettings.isLetterIdenticon: !!name spacing: 0
assetSettings.bgHeight: 32 ButtonGroup {
assetSettings.bgWidth: 32 id: recentsButtonGroup
assetSettings.bgRadius: assetSettings.bgHeight/2 exclusive: false
assetSettings.width: 16
assetSettings.height: 16
buttonGroup: recentsButtonGroup
allChecked: root.allRecentsChecked
checked: root.allRecentsChecked ? true : root.recentsFilters.includes(model.address)
onActionTriggered: root.recentsToggled(model.address)
} }
} StatusBaseText {
} Layout.alignment: Qt.AlignHCenter
text: qsTr("No Recents")
Column { visible: recipientsListView.count === 0 && !root.loadingRecipients
id: column2 }
Layout.fillWidth: true StatusBaseText {
spacing: 0 Layout.alignment: Qt.AlignHCenter
ButtonGroup { text: qsTr("Loading Recents")
id: savedButtonGroup visible: root.loadingRecipients
exclusive: false }
} StatusListView {
StatusBaseText { id: recipientsListView
anchors.horizontalCenter: parent.horizontalCenter visible: !root.loadingRecipients
text: qsTr("No Saved Address") Layout.fillWidth: true
visible: root.savedAddressList.count === 0 Layout.fillHeight: true
} model: SortFilterProxyModel {
StatusListView { sourceModel: root.recentsList
width: parent.width filters: ExpressionFilter {
height: root.height - tabBar.height - 12 enabled: root.recentsList.count > 0 && layout.currentIndex === 0
model: root.savedAddressList expression: {
delegate: ActivityTypeCheckBox { const searchValue = searchBox.searchValue
width: ListView.view.width if (!searchValue)
height: 44 return true
title: model.name ?? "" const address = model.address.toLowerCase()
subTitle: { return address.startsWith(searchValue) || store.getNameForAddress(address).toLowerCase().indexOf(searchValue) !== -1
if (model.ens.length > 0) { }
return sensor.containsMouse ? Utils.richColorText(model.ens, Theme.palette.directColor1) : model.ens
}
else {
let elidedAddress = StatusQUtils.Utils.elideText(model.address,6,4)
return sensor.containsMouse ? WalletUtils.colorizedChainPrefix(model.chainShortNames) + Utils.richColorText(elidedAddress, Theme.palette.directColor1): model.chainShortNames + elidedAddress
} }
} }
statusListItemSubTitle.elide: Text.ElideMiddle
statusListItemSubTitle.wrapMode: Text.NoWrap reuseItems: true
assetSettings.name: model.name delegate: ActivityTypeCheckBox {
assetSettings.isLetterIdenticon: true readonly property string name: store.getNameForAddress(model.address)
buttonGroup: savedButtonGroup width: ListView.view.width
allChecked: root.allSavedAddressesChecked height: 44
checked: root.allSavedAddressesChecked ? true : root.savedAddressFilters.includes(model.address) title: name || StatusQUtils.Utils.elideText(model.address,6,4)
onActionTriggered: root.savedAddressToggled(model.address) subTitle: name ? StatusQUtils.Utils.elideText(model.address,6,4): ""
statusListItemSubTitle.elide: Text.ElideMiddle
statusListItemSubTitle.wrapMode: Text.NoWrap
assetSettings.name: name || "address"
assetSettings.isLetterIdenticon: !!name
assetSettings.bgHeight: 32
assetSettings.bgWidth: 32
assetSettings.bgRadius: assetSettings.bgHeight/2
assetSettings.width: !!name ? 32 : 16
assetSettings.height: !!name ? 32 : 16
buttonGroup: recentsButtonGroup
allChecked: root.allRecentsChecked
checked: root.allRecentsChecked ? true : root.recentsFilters.includes(model.address)
onActionTriggered: root.recentsToggled(model.address)
}
}
}
ColumnLayout {
id: column2
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
ButtonGroup {
id: savedButtonGroup
exclusive: false
}
StatusBaseText {
Layout.alignment: Qt.AlignHCenter
text: qsTr("No Saved Address")
visible: savedAddressesListView.count === 0
}
StatusListView {
id: savedAddressesListView
Layout.fillWidth: true
Layout.fillHeight: true
model: SortFilterProxyModel {
sourceModel: root.savedAddressList
filters: ExpressionFilter {
enabled: root.savedAddressList.count > 0 && layout.currentIndex === 1
expression: {
const searchValue = searchBox.searchValue
if (!searchValue)
return true
return model.name.toLowerCase().indexOf(searchValue) !== -1
|| model.address.toLowerCase().startsWith(searchValue)
|| model.ens.toLowerCase().startsWith(searchValue)
}
}
}
delegate: ActivityTypeCheckBox {
width: ListView.view.width
height: 44
title: model.name ?? ""
subTitle: {
if (model.ens.length > 0) {
return sensor.containsMouse ? Utils.richColorText(model.ens, Theme.palette.directColor1) : model.ens
}
else {
let elidedAddress = StatusQUtils.Utils.elideText(model.address,6,4)
return sensor.containsMouse ? WalletUtils.colorizedChainPrefix(model.chainShortNames) + Utils.richColorText(elidedAddress, Theme.palette.directColor1): model.chainShortNames + elidedAddress
}
}
statusListItemSubTitle.elide: Text.ElideMiddle
statusListItemSubTitle.wrapMode: Text.NoWrap
assetSettings.name: model.name
assetSettings.isLetterIdenticon: true
assetSettings.bgHeight: 32
assetSettings.bgWidth: 32
assetSettings.width: 32
assetSettings.height: 32
buttonGroup: savedButtonGroup
allChecked: root.allSavedAddressesChecked
checked: root.allSavedAddressesChecked ? true : root.savedAddressFilters.includes(model.address)
onActionTriggered: root.savedAddressToggled(model.address)
}
} }
} }
} }
} }
} }

View File

@ -28,7 +28,7 @@ StatusMenu {
signal tokenToggled(string tokenSymbol) signal tokenToggled(string tokenSymbol)
signal collectibleToggled(double id) signal collectibleToggled(double id)
property var searchTokenSymbolByAddressFn: function (address) { return "" } property var searchTokenSymbolByAddressFn: function (address) { return "" } // TODO
implicitWidth: 289 implicitWidth: 289
@ -37,140 +37,148 @@ StatusMenu {
property bool isFetching: root.collectiblesList.isFetching property bool isFetching: root.collectiblesList.isFetching
} }
MenuBackButton { contentItem: ColumnLayout {
id: backButton spacing: 12
width: parent.width MenuBackButton {
onClicked: { id: backButton
close()
back()
}
}
StatusSwitchTabBar {
id: tabBar
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: backButton.bottom
anchors.topMargin: 12
width: parent.width - 16
StatusSwitchTabButton {
text: qsTr("Assets")
}
StatusSwitchTabButton {
text: qsTr("Collectibles")
}
}
StackLayout {
id: layout
width: parent.width
anchors.top: tabBar.bottom
anchors.topMargin: 12
currentIndex: tabBar.currentIndex
Column {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 8 onClicked: {
close()
ButtonGroup { back()
id: tokenButtonGroup
exclusive: false
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("No Assets")
visible: root.tokensList.count === 0
}
SearchBox {
id: tokensSearchBox
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width - 16
input.height: 36
placeholderText: qsTr("Search asset name")
}
StatusListView {
width: parent.width
height: root.height - tabBar.height - tokensSearchBox.height - 12
spacing: 0
model: SortFilterProxyModel {
sourceModel: root.tokensList
filters: ExpressionFilter {
enabled: root.tokensList.count > 0
expression: {
var tokenSymbolByAddress = root.searchTokenSymbolByAddressFn(tokensSearchBox.text)
return symbol.startsWith(tokensSearchBox.text.toUpperCase()) || name.toUpperCase().startsWith(tokensSearchBox.text.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
}
}
}
delegate: ActivityTypeCheckBox {
width: ListView.view.width
height: 44
title: model.name
titleAsideText: model.symbol
assetSettings.name: model.symbol ? Constants.tokenIcon(symbol) : ""
assetSettings.isImage: true
buttonGroup: tokenButtonGroup
allChecked: root.allTokensChecked
checked: root.allTokensChecked || root.tokensFilter.includes(model.symbol)
onActionTriggered: root.tokenToggled(model.symbol)
}
} }
} }
Column { StatusSwitchTabBar {
width: parent.width id: tabBar
spacing: 8 Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
ButtonGroup { Layout.leftMargin: 8
id: collectibleButtonGroup Layout.rightMargin: 8
exclusive: false StatusSwitchTabButton {
text: qsTr("Assets")
} }
StatusSwitchTabButton {
StatusBaseText { text: qsTr("Collectibles")
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("No Collectibles")
visible: root.collectiblesList.count === 0
} }
}
SearchBox { StackLayout {
id: collectiblesSearchBox id: layout
anchors.horizontalCenter: parent.horizontalCenter Layout.fillWidth: true
width: parent.width - 16 Layout.fillHeight: true
input.height: 36 currentIndex: tabBar.currentIndex
placeholderText: qsTr("Search collectible name")
}
StatusListView { ColumnLayout {
width: parent.width Layout.fillWidth: true
height: root.height - tabBar.height - tokensSearchBox.height - 12 Layout.fillHeight: true
spacing: 0 spacing: 8
reuseItems: true
model: SortFilterProxyModel { ButtonGroup {
sourceModel: root.collectiblesList id: tokenButtonGroup
filters: ExpressionFilter { exclusive: false
enabled: root.collectiblesList.count > 0 && !!collectiblesSearchBox.text }
expression: {
let searchText = collectiblesSearchBox.text.toUpperCase() StatusBaseText {
return name.toUpperCase().startsWith(searchText) Layout.alignment: Qt.AlignHCenter
text: qsTr("No Assets")
visible: root.tokensList.count === 0
}
SearchBox {
id: tokensSearchBox
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: 8
Layout.rightMargin: 8
input.height: 36
placeholderText: qsTr("Search asset name")
}
StatusListView {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
model: SortFilterProxyModel {
sourceModel: root.tokensList
filters: ExpressionFilter {
enabled: root.tokensList.count > 0
expression: {
const tokenSymbolByAddress = root.searchTokenSymbolByAddressFn(tokensSearchBox.text)
return symbol.startsWith(tokensSearchBox.text.toUpperCase()) || name.toUpperCase().startsWith(tokensSearchBox.text.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
}
} }
} }
delegate: ActivityTypeCheckBox {
width: ListView.view.width
height: 44
title: model.name
titleAsideText: model.symbol
assetSettings.name: model.symbol ? Constants.tokenIcon(symbol) : ""
assetSettings.isImage: true
buttonGroup: tokenButtonGroup
allChecked: root.allTokensChecked
checked: root.allTokensChecked || root.tokensFilter.includes(model.symbol)
onActionTriggered: root.tokenToggled(model.symbol)
}
} }
delegate: ActivityTypeCheckBox { }
width: ListView.view.width
height: 44 ColumnLayout {
title: model.name Layout.fillWidth: true
assetSettings.name: model.imageUrl Layout.fillHeight: true
assetSettings.isImage: true spacing: 8
assetSettings.bgWidth: 32
assetSettings.bgHeight: 32 ButtonGroup {
assetSettings.bgRadius: assetSettings.bgHeight/2 id: collectibleButtonGroup
buttonGroup: collectibleButtonGroup exclusive: false
allChecked: root.allCollectiblesChecked }
checked: root.allCollectiblesChecked || root.collectiblesFilter.includes(model.id)
onActionTriggered: root.collectibleToggled(model.id) StatusBaseText {
loading: d.isFetching Layout.alignment: Qt.AlignHCenter
text: qsTr("No Collectibles")
visible: root.collectiblesList.count === 0
}
SearchBox {
id: collectiblesSearchBox
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: 8
Layout.rightMargin: 8
input.height: 36
placeholderText: qsTr("Search collectible name")
}
StatusListView {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
reuseItems: true
model: SortFilterProxyModel {
sourceModel: root.collectiblesList
filters: ExpressionFilter {
enabled: root.collectiblesList.count > 0 && !!collectiblesSearchBox.text
expression: {
const searchText = collectiblesSearchBox.text.toUpperCase()
return name.toUpperCase().startsWith(searchText)
}
}
}
delegate: ActivityTypeCheckBox {
width: ListView.view.width
height: 44
title: model.name
assetSettings.name: model.imageUrl
assetSettings.isImage: true
assetSettings.bgWidth: 32
assetSettings.bgHeight: 32
assetSettings.bgRadius: assetSettings.bgHeight/2
buttonGroup: collectibleButtonGroup
allChecked: root.allCollectiblesChecked
checked: root.allCollectiblesChecked || root.collectiblesFilter.includes(model.id)
onActionTriggered: root.collectibleToggled(model.id)
loading: d.isFetching
}
} }
} }
} }

View File

@ -486,6 +486,7 @@ Item {
} }
} }
tertiaryTitle: !d.loadingInputDate && !d.decodedInputData ? qsTr("Data could not be decoded") : "" tertiaryTitle: !d.loadingInputDate && !d.decodedInputData ? qsTr("Data could not be decoded") : ""
statusListItemTertiaryTitle.anchors.top: undefined
statusListItemTertiaryTitle.anchors.baseline: statusListItemTitle.baseline statusListItemTertiaryTitle.anchors.baseline: statusListItemTitle.baseline
statusListItemTertiaryTitle.font: statusListItemTitle.font statusListItemTertiaryTitle.font: statusListItemTitle.font
onButtonClicked: addressMenu.openInputDataMenu(this, !!d.decodedInputData ? d.decodedInputData : root.transaction.input) onButtonClicked: addressMenu.openInputDataMenu(this, !!d.decodedInputData ? d.decodedInputData : root.transaction.input)