fix(@desktop/wallet): Activity UI filtering improvements
1. Handling case where filters result in no results 2. Fixed period filter 3. Used recipient model from go side
This commit is contained in:
parent
ae9a52397c
commit
9be598ee32
|
@ -370,8 +370,9 @@ QtObject:
|
||||||
error "error fetching recipients: ", response.error
|
error "error fetching recipients: ", response.error
|
||||||
return
|
return
|
||||||
|
|
||||||
let result = json.to(response.result, backend_activity.GetAllRecipientsResponse)
|
if response.result["addresses"] != newJNull():
|
||||||
self.recipientsModel.addAddresses(result.addresses, 0, result.hasMore)
|
let result = json.to(response.result, backend_activity.GetAllRecipientsResponse)
|
||||||
|
self.recipientsModel.addAddresses(deduplicate(result.addresses), 0, result.hasMore)
|
||||||
|
|
||||||
proc loadMoreRecipients(self: Controller) {.slot.} =
|
proc loadMoreRecipients(self: Controller) {.slot.} =
|
||||||
let response = backend_activity.getAllRecipients(self.recipientsModel.getCount(), FETCH_RECIPIENTS_BATCH_COUNT_DEFAULT)
|
let response = backend_activity.getAllRecipients(self.recipientsModel.getCount(), FETCH_RECIPIENTS_BATCH_COUNT_DEFAULT)
|
||||||
|
@ -379,8 +380,9 @@ QtObject:
|
||||||
error "error fetching more recipient entries: ", response.error
|
error "error fetching more recipient entries: ", response.error
|
||||||
return
|
return
|
||||||
|
|
||||||
let result = json.to(response.result, backend_activity.GetAllRecipientsResponse)
|
if response.result["addresses"] != newJNull():
|
||||||
self.recipientsModel.addAddresses(result.addresses, self.recipientsModel.getCount(), result.hasMore)
|
let result = json.to(response.result, backend_activity.GetAllRecipientsResponse)
|
||||||
|
self.recipientsModel.addAddresses(deduplicate(result.addresses), self.recipientsModel.getCount(), result.hasMore)
|
||||||
|
|
||||||
proc getStartTimestamp*(self: Controller): int {.slot.} =
|
proc getStartTimestamp*(self: Controller): int {.slot.} =
|
||||||
return if self.startTimestamp > 0:
|
return if self.startTimestamp > 0:
|
||||||
|
|
|
@ -7,171 +7,200 @@ import StatusQ.Controls 0.1
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
|
import shared.panels 1.0
|
||||||
|
|
||||||
import "../controls"
|
import "../controls"
|
||||||
import "../popups"
|
import "../popups"
|
||||||
|
|
||||||
Flow {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var activityFilterStore
|
property var activityFilterStore
|
||||||
property var store
|
property var store
|
||||||
|
property bool isLoading: false
|
||||||
|
|
||||||
spacing: 8
|
spacing: 12
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
activityFilterStore.updateFilterBase()
|
activityFilterStore.updateFilterBase()
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusRoundButton {
|
Flow {
|
||||||
id: filterButton
|
width: parent.width
|
||||||
width: 32
|
|
||||||
height: 32
|
|
||||||
icon.name: "filter"
|
|
||||||
border.width: 1
|
|
||||||
border.color: Theme.palette.directColor8
|
|
||||||
type: StatusRoundButton.Type.Tertiary
|
|
||||||
onClicked: activityFilterMenu.popup(x, y + height + 4)
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityFilterTagItem {
|
spacing: 8
|
||||||
tagPrimaryLabel.text: LocaleUtils.formatDate(activityFilterStore.fromTimestamp)
|
|
||||||
tagSecondaryLabel.text: {
|
StatusRoundButton {
|
||||||
switch(activityFilterMenu.selectedTime) {
|
id: filterButton
|
||||||
case Constants.TransactionTimePeriod.Today:
|
width: 32
|
||||||
case Constants.TransactionTimePeriod.Yesterday:
|
height: 32
|
||||||
return ""
|
icon.name: "filter"
|
||||||
default:
|
border.width: 1
|
||||||
return LocaleUtils.formatDate(activityFilterStore.toTimestamp)
|
border.color: Theme.palette.directColor8
|
||||||
|
type: StatusRoundButton.Type.Tertiary
|
||||||
|
icon.color: Theme.palette.primaryColor1
|
||||||
|
onClicked: activityFilterMenu.popup(x, y + height + 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityFilterTagItem {
|
||||||
|
tagPrimaryLabel.text: LocaleUtils.formatDate(activityFilterStore.fromTimestamp)
|
||||||
|
tagSecondaryLabel.text: {
|
||||||
|
switch(activityFilterMenu.selectedTime) {
|
||||||
|
case Constants.TransactionTimePeriod.Today:
|
||||||
|
case Constants.TransactionTimePeriod.Yesterday:
|
||||||
|
return ""
|
||||||
|
default:
|
||||||
|
return LocaleUtils.formatDate(activityFilterStore.toTimestamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
middleLabel.text: {
|
||||||
|
switch(activityFilterMenu.selectedTime) {
|
||||||
|
case Constants.TransactionTimePeriod.Today:
|
||||||
|
case Constants.TransactionTimePeriod.Yesterday:
|
||||||
|
return ""
|
||||||
|
default:
|
||||||
|
return qsTr("to")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iconAsset.icon: "history"
|
||||||
|
visible: activityFilterMenu.selectedTime !== Constants.TransactionTimePeriod.All
|
||||||
|
onClosed: activityFilterStore.setSelectedTimestamp(Constants.TransactionTimePeriod.All)
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: activityFilterMenu.allTypesChecked ? 0: activityFilterStore.typeFilters
|
||||||
|
delegate: ActivityFilterTagItem {
|
||||||
|
property int type: activityFilterStore.typeFilters[index]
|
||||||
|
tagPrimaryLabel.text: switch(activityFilterStore.typeFilters[index]) {
|
||||||
|
case Constants.TransactionType.Send:
|
||||||
|
return qsTr("Send")
|
||||||
|
case Constants.TransactionType.Receive:
|
||||||
|
return qsTr("Receive")
|
||||||
|
case Constants.TransactionType.Buy:
|
||||||
|
return qsTr("Buy")
|
||||||
|
case Constants.TransactionType.Swap:
|
||||||
|
return qsTr("Swap")
|
||||||
|
case Constants.TransactionType.Bridge:
|
||||||
|
return qsTr("Bridge")
|
||||||
|
default:
|
||||||
|
console.warn("Unhandled type :: ",activityFilterStore.typeFilters[index])
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
iconAsset.icon: switch(activityFilterStore.typeFilters[index]) {
|
||||||
|
case Constants.TransactionType.Send:
|
||||||
|
return "send"
|
||||||
|
case Constants.TransactionType.Receive:
|
||||||
|
return "receive"
|
||||||
|
case Constants.TransactionType.Buy:
|
||||||
|
return "token"
|
||||||
|
case Constants.TransactionType.Swap:
|
||||||
|
return "swap"
|
||||||
|
case Constants.TransactionType.Bridge:
|
||||||
|
return "bridge"
|
||||||
|
default:
|
||||||
|
console.warn("Unhandled type :: ",activityFilterStore.typeFilters[index])
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
onClosed: activityFilterStore.toggleType(type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
middleLabel.text: {
|
|
||||||
switch(activityFilterMenu.selectedTime) {
|
Repeater {
|
||||||
case Constants.TransactionTimePeriod.Today:
|
model: activityFilterMenu.allStatusChecked ? 0 : activityFilterStore.statusFilters
|
||||||
case Constants.TransactionTimePeriod.Yesterday:
|
delegate: ActivityFilterTagItem {
|
||||||
return ""
|
property int status: activityFilterStore.statusFilters[index]
|
||||||
default:
|
tagPrimaryLabel.text: switch(activityFilterStore.statusFilters[index]) {
|
||||||
return qsTr("to")
|
case Constants.TransactionStatus.Failed:
|
||||||
|
return qsTr("Failed")
|
||||||
|
case Constants.TransactionStatus.Pending:
|
||||||
|
return qsTr("Pending")
|
||||||
|
case Constants.TransactionStatus.Complete:
|
||||||
|
return qsTr("Complete")
|
||||||
|
case Constants.TransactionStatus.Finished:
|
||||||
|
return qsTr("Finalised")
|
||||||
|
default:
|
||||||
|
console.warn("Unhandled status :: ",activityFilterStore.statusFilters[index])
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
iconAsset.icon: switch(activityFilterStore.statusFilters[index]) {
|
||||||
|
case Constants.TransactionStatus.Failed:
|
||||||
|
return Style.svg("transaction/failed")
|
||||||
|
case Constants.TransactionStatus.Pending:
|
||||||
|
return Style.svg("transaction/pending")
|
||||||
|
case Constants.TransactionStatus.Complete:
|
||||||
|
return Style.svg("transaction/verified")
|
||||||
|
case Constants.TransactionStatus.Finished:
|
||||||
|
return Style.svg("transaction/finished")
|
||||||
|
default:
|
||||||
|
console.warn("Unhandled status :: ",activityFilterStore.statusFilters[index])
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
iconAsset.color: "transparent"
|
||||||
|
onClosed: activityFilterStore.toggleStatus(status, activityFilterMenu.allStatusChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iconAsset.icon: "history"
|
|
||||||
visible: activityFilterMenu.selectedTime !== Constants.TransactionTimePeriod.All
|
|
||||||
onClosed: activityFilterStore.setSelectedTimestamp(Constants.TransactionTimePeriod.All)
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: activityFilterMenu.allTypesChecked ? 0: activityFilterStore.typeFilters
|
model: activityFilterStore.tokensList
|
||||||
delegate: ActivityFilterTagItem {
|
delegate: ActivityFilterTagItem {
|
||||||
property int type: activityFilterStore.typeFilters[index]
|
tagPrimaryLabel.text: symbol
|
||||||
tagPrimaryLabel.text: switch(activityFilterStore.typeFilters[index]) {
|
iconAsset.icon: Constants.tokenIcon(symbol)
|
||||||
case Constants.TransactionType.Send:
|
iconAsset.color: "transparent"
|
||||||
return qsTr("Send")
|
visible: !activityFilterMenu.allTokensChecked && activityFilterStore.tokensFilter.includes(symbol)
|
||||||
case Constants.TransactionType.Receive:
|
onClosed: activityFilterStore.toggleToken(symbol)
|
||||||
return qsTr("Receive")
|
}
|
||||||
case Constants.TransactionType.Buy:
|
}
|
||||||
return qsTr("Buy")
|
|
||||||
case Constants.TransactionType.Swap:
|
Repeater {
|
||||||
return qsTr("Swap")
|
model: activityFilterStore.collectiblesList
|
||||||
case Constants.TransactionType.Bridge:
|
delegate: ActivityFilterTagItem {
|
||||||
return qsTr("Bridge")
|
tagPrimaryLabel.text: model.name
|
||||||
default:
|
iconAsset.icon: model.imageUrl
|
||||||
console.warn("Unhandled type :: ",activityFilterStore.typeFilters[index])
|
iconAsset.color: "transparent"
|
||||||
return ""
|
visible: !activityFilterMenu.allCollectiblesChecked && activityFilterStore.collectiblesFilter.includes(model.id)
|
||||||
}
|
onClosed: activityFilterStore.toggleCollectibles(model.id)
|
||||||
iconAsset.icon: switch(activityFilterStore.typeFilters[index]) {
|
}
|
||||||
case Constants.TransactionType.Send:
|
}
|
||||||
return "send"
|
|
||||||
case Constants.TransactionType.Receive:
|
Repeater {
|
||||||
return "receive"
|
model: activityFilterStore.recentsList
|
||||||
case Constants.TransactionType.Buy:
|
delegate: ActivityFilterTagItem {
|
||||||
return "token"
|
tagPrimaryLabel.text: root.store.getNameForAddress(model.address) || StatusQUtils.Utils.elideText(model.address,6,4)
|
||||||
case Constants.TransactionType.Swap:
|
visible: !activityFilterMenu.allRecentsChecked && activityFilterMenu.recentsFilters.includes(model.address)
|
||||||
return "swap"
|
onClosed: activityFilterStore.toggleRecents(model.address)
|
||||||
case Constants.TransactionType.Bridge:
|
}
|
||||||
return "bridge"
|
}
|
||||||
default:
|
|
||||||
console.warn("Unhandled type :: ",activityFilterStore.typeFilters[index])
|
Repeater {
|
||||||
return ""
|
model: activityFilterStore.savedAddressList
|
||||||
}
|
delegate: ActivityFilterTagItem {
|
||||||
onClosed: activityFilterStore.toggleType(type)
|
tagPrimaryLabel.text: ens.length > 0 ? ens : chainShortNames + StatusQUtils.Utils.elideText(address,6,4)
|
||||||
|
visible: !activityFilterMenu.allSavedAddressesChecked && activityFilterMenu.savedAddressFilters.includes(address)
|
||||||
|
onClosed: activityFilterStore.toggleSavedAddress(address)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Separator {
|
||||||
model: activityFilterMenu.allStatusChecked ? 0 : activityFilterStore.statusFilters
|
visible: noResultsAfterFilter.visible
|
||||||
delegate: ActivityFilterTagItem {
|
|
||||||
property int status: activityFilterStore.statusFilters[index]
|
|
||||||
tagPrimaryLabel.text: switch(activityFilterStore.statusFilters[index]) {
|
|
||||||
case Constants.TransactionStatus.Failed:
|
|
||||||
return qsTr("Failed")
|
|
||||||
case Constants.TransactionStatus.Pending:
|
|
||||||
return qsTr("Pending")
|
|
||||||
case Constants.TransactionStatus.Complete:
|
|
||||||
return qsTr("Complete")
|
|
||||||
case Constants.TransactionStatus.Finished:
|
|
||||||
return qsTr("Finalised")
|
|
||||||
default:
|
|
||||||
console.warn("Unhandled status :: ",activityFilterStore.statusFilters[index])
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
iconAsset.icon: switch(activityFilterStore.statusFilters[index]) {
|
|
||||||
case Constants.TransactionStatus.Failed:
|
|
||||||
return Style.svg("transaction/failed")
|
|
||||||
case Constants.TransactionStatus.Pending:
|
|
||||||
return Style.svg("transaction/pending")
|
|
||||||
case Constants.TransactionStatus.Complete:
|
|
||||||
return Style.svg("transaction/verified")
|
|
||||||
case Constants.TransactionStatus.Finished:
|
|
||||||
return Style.svg("transaction/finished")
|
|
||||||
default:
|
|
||||||
console.warn("Unhandled status :: ",activityFilterStore.statusFilters[index])
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
iconAsset.color: "transparent"
|
|
||||||
onClosed: activityFilterStore.toggleStatus(status, activityFilterMenu.allStatusChecked)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
StatusBaseText {
|
||||||
model: activityFilterStore.tokensList
|
id: noResultsAfterFilter
|
||||||
delegate: ActivityFilterTagItem {
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
tagPrimaryLabel.text: symbol
|
anchors.topMargin: 16
|
||||||
iconAsset.icon: Constants.tokenIcon(symbol)
|
visible: !root.isLoading && activityFilterStore.transactionsList.count === 0 && activityFilterStore.filtersSet
|
||||||
iconAsset.color: "transparent"
|
text: qsTr("No activity items for the current filter")
|
||||||
visible: !activityFilterMenu.allTokensChecked && activityFilterStore.tokensFilter.includes(symbol)
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
onClosed: activityFilterStore.toggleToken(symbol)
|
color: Theme.palette.baseColor1
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
StatusButton {
|
||||||
model: activityFilterStore.collectiblesList
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
delegate: ActivityFilterTagItem {
|
visible: noResultsAfterFilter.visible
|
||||||
tagPrimaryLabel.text: model.name
|
text: qsTr("Clear all filters")
|
||||||
iconAsset.icon: model.imageUrl
|
size: StatusBaseButton.Size.Small
|
||||||
iconAsset.color: "transparent"
|
onClicked: activityFilterStore.resetAllFilters()
|
||||||
visible: !activityFilterMenu.allCollectiblesChecked && activityFilterStore.collectiblesFilter.includes(model.id)
|
|
||||||
onClosed: activityFilterStore.toggleCollectibles(model.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: activityFilterStore.recentsList
|
|
||||||
delegate: ActivityFilterTagItem {
|
|
||||||
property int transactionType: to.toLowerCase() === root.store.overview.mixedcaseAddress.toLowerCase() ? Constants.TransactionType.Receive : Constants.TransactionType.Send
|
|
||||||
tagPrimaryLabel.text: transactionType === Constants.TransactionType.Receive ?
|
|
||||||
root.store.getNameForAddress(from) || StatusQUtils.Utils.elideText(from,6,4) :
|
|
||||||
root.store.getNameForAddress(to) || StatusQUtils.Utils.elideText(to,6,4)
|
|
||||||
visible: !activityFilterMenu.allRecentsChecked && activityFilterMenu.recentsFilters.includes(transactionType === Constants.TransactionType.Receive ? from : to)
|
|
||||||
onClosed: activityFilterStore.toggleRecents(transactionType === Constants.TransactionType.Receive ? from : to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: activityFilterStore.savedAddressList
|
|
||||||
delegate: ActivityFilterTagItem {
|
|
||||||
tagPrimaryLabel.text: ens.length > 0 ? ens : chainShortNames + StatusQUtils.Utils.elideText(address,6,4)
|
|
||||||
visible: !activityFilterMenu.allSavedAddressesChecked && activityFilterMenu.savedAddressFilters.includes(address)
|
|
||||||
onClosed: activityFilterStore.toggleSavedAddress(address)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityFilterMenu {
|
ActivityFilterMenu {
|
||||||
|
@ -207,6 +236,7 @@ Flow {
|
||||||
savedAddressFilters: activityFilterStore.savedAddressFilters
|
savedAddressFilters: activityFilterStore.savedAddressFilters
|
||||||
onUpdateSavedAddressFilter: activityFilterStore.toggleSavedAddress(address)
|
onUpdateSavedAddressFilter: activityFilterStore.toggleSavedAddress(address)
|
||||||
onUpdateRecentsFilter: activityFilterStore.toggleRecents(address)
|
onUpdateRecentsFilter: activityFilterStore.toggleRecents(address)
|
||||||
|
onUpdateRecipientsModel: activityFilterStore.updateRecipientsModel()
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusDateRangePicker {
|
StatusDateRangePicker {
|
||||||
|
|
|
@ -41,6 +41,7 @@ StatusMenu {
|
||||||
property var recentsFilters
|
property var recentsFilters
|
||||||
readonly property bool allRecentsChecked: counterPartyMenu.allRecentsChecked
|
readonly property bool allRecentsChecked: counterPartyMenu.allRecentsChecked
|
||||||
signal updateRecentsFilter(string address)
|
signal updateRecentsFilter(string address)
|
||||||
|
signal updateRecipientsModel()
|
||||||
|
|
||||||
// Collectibles filter
|
// Collectibles filter
|
||||||
property var savedAddressList
|
property var savedAddressList
|
||||||
|
@ -103,6 +104,7 @@ StatusMenu {
|
||||||
savedAddressFilters: root.savedAddressFilters
|
savedAddressFilters: root.savedAddressFilters
|
||||||
onSavedAddressToggled: root.updateSavedAddressFilter(address)
|
onSavedAddressToggled: root.updateSavedAddressFilter(address)
|
||||||
onRecentsToggled: root.updateRecentsFilter(address)
|
onRecentsToggled: root.updateRecentsFilter(address)
|
||||||
|
onUpdateRecipientsModel: root.updateRecipientsModel()
|
||||||
closePolicy: root.closePolicy
|
closePolicy: root.closePolicy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,12 @@ StatusMenu {
|
||||||
signal back()
|
signal back()
|
||||||
signal savedAddressToggled(string address)
|
signal savedAddressToggled(string address)
|
||||||
signal recentsToggled(string address)
|
signal recentsToggled(string address)
|
||||||
|
signal updateRecipientsModel()
|
||||||
|
|
||||||
implicitWidth: 289
|
implicitWidth: 289
|
||||||
|
|
||||||
|
Component.onCompleted: root.updateRecipientsModel()
|
||||||
|
|
||||||
MenuBackButton {
|
MenuBackButton {
|
||||||
id: backButton
|
id: backButton
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -74,28 +77,25 @@ StatusMenu {
|
||||||
id: recentsButtonGroup
|
id: recentsButtonGroup
|
||||||
exclusive: false
|
exclusive: false
|
||||||
}
|
}
|
||||||
Repeater {
|
StatusBaseText {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("No Recents")
|
||||||
|
visible: root.recentsList.count === 0
|
||||||
|
}
|
||||||
|
StatusListView {
|
||||||
|
width: parent.width
|
||||||
|
height: root.height - tabBar.height - 12
|
||||||
model: root.recentsList
|
model: root.recentsList
|
||||||
delegate: ActivityTypeCheckBox {
|
delegate: ActivityTypeCheckBox {
|
||||||
readonly property int transactionType: model.activityEntry.recipient.toLowerCase() === store.overview.mixedcaseAddress.toLowerCase() ? Constants.TransactionType.Receive : Constants.TransactionType.Send
|
readonly property string name: store.getNameForAddress(model.address)
|
||||||
readonly property string fromName: store.getNameForAddress(model.activityEntry.sender)
|
width: ListView.view.width
|
||||||
readonly property string toName: store.getNameForAddress(model.activityEntry.recipient)
|
|
||||||
width: parent.width
|
|
||||||
height: 44
|
height: 44
|
||||||
title: transactionType === Constants.TransactionType.Receive ?
|
title: name || StatusQUtils.Utils.elideText(model.address,6,4)
|
||||||
fromName || StatusQUtils.Utils.elideText(model.activityEntry.sender,6,4) :
|
subTitle: name ? StatusQUtils.Utils.elideText(model.address,6,4): ""
|
||||||
toName || StatusQUtils.Utils.elideText(model.activityEntry.recipient,6,4)
|
|
||||||
subTitle: {
|
|
||||||
if (transactionType === Constants.TransactionType.Receive) {
|
|
||||||
return fromName ? StatusQUtils.Utils.elideText(model.activityEntry.sender,6,4) : ""
|
|
||||||
} else {
|
|
||||||
return toName ? StatusQUtils.Utils.elideText(model.activityEntry.recipient,6,4): ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statusListItemSubTitle.elide: Text.ElideMiddle
|
statusListItemSubTitle.elide: Text.ElideMiddle
|
||||||
statusListItemSubTitle.wrapMode: Text.NoWrap
|
statusListItemSubTitle.wrapMode: Text.NoWrap
|
||||||
assetSettings.name: (transactionType === Constants.TransactionType.Receive ? fromName : toName) || "address"
|
assetSettings.name: name || "address"
|
||||||
assetSettings.isLetterIdenticon: transactionType === Constants.TransactionType.Receive ? !!fromName : !!toName
|
assetSettings.isLetterIdenticon: !!name
|
||||||
assetSettings.bgHeight: 32
|
assetSettings.bgHeight: 32
|
||||||
assetSettings.bgWidth: 32
|
assetSettings.bgWidth: 32
|
||||||
assetSettings.bgRadius: assetSettings.bgHeight/2
|
assetSettings.bgRadius: assetSettings.bgHeight/2
|
||||||
|
@ -103,8 +103,8 @@ StatusMenu {
|
||||||
assetSettings.height: 16
|
assetSettings.height: 16
|
||||||
buttonGroup: recentsButtonGroup
|
buttonGroup: recentsButtonGroup
|
||||||
allChecked: root.allRecentsChecked
|
allChecked: root.allRecentsChecked
|
||||||
checked: root.allRecentsChecked ? true : root.recentsFilters.includes(transactionType === Constants.TransactionType.Receive ? model.activityEntry.sender: model.activityEntry.recipient)
|
checked: root.allRecentsChecked ? true : root.recentsFilters.includes(model.address)
|
||||||
onActionTriggered: root.recentsToggled(transactionType === Constants.TransactionType.Receive ? model.activityEntry.sender: model.activityEntry.recipient)
|
onActionTriggered: root.recentsToggled(model.address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,17 @@ StatusMenu {
|
||||||
id: savedButtonGroup
|
id: savedButtonGroup
|
||||||
exclusive: false
|
exclusive: false
|
||||||
}
|
}
|
||||||
Repeater {
|
StatusBaseText {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("No Saved Address")
|
||||||
|
visible: root.savedAddressList.count === 0
|
||||||
|
}
|
||||||
|
StatusListView {
|
||||||
|
width: parent.width
|
||||||
|
height: root.height - tabBar.height - 12
|
||||||
model: root.savedAddressList
|
model: root.savedAddressList
|
||||||
delegate: ActivityTypeCheckBox {
|
delegate: ActivityTypeCheckBox {
|
||||||
width: parent.width
|
width: ListView.view.width
|
||||||
height: 44
|
height: 44
|
||||||
title: model.name ?? ""
|
title: model.name ?? ""
|
||||||
subTitle: {
|
subTitle: {
|
||||||
|
|
|
@ -76,6 +76,12 @@ StatusMenu {
|
||||||
exclusive: false
|
exclusive: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("No Assets")
|
||||||
|
visible: root.tokensList.count === 0
|
||||||
|
}
|
||||||
|
|
||||||
SearchBox {
|
SearchBox {
|
||||||
id: tokensSearchBox
|
id: tokensSearchBox
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -84,32 +90,31 @@ StatusMenu {
|
||||||
placeholderText: qsTr("Search asset name")
|
placeholderText: qsTr("Search asset name")
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
StatusListView {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
height: root.height - tabBar.height - tokensSearchBox.height - 12
|
||||||
spacing: 0
|
spacing: 0
|
||||||
Repeater {
|
model: SortFilterProxyModel {
|
||||||
model: SortFilterProxyModel {
|
sourceModel: root.tokensList
|
||||||
sourceModel: root.tokensList
|
filters: ExpressionFilter {
|
||||||
filters: ExpressionFilter {
|
enabled: root.tokensList.count > 0
|
||||||
enabled: root.tokensList.count > 0
|
expression: {
|
||||||
expression: {
|
var tokenSymbolByAddress = root.searchTokenSymbolByAddressFn(tokensSearchBox.text)
|
||||||
var tokenSymbolByAddress = root.searchTokenSymbolByAddressFn(tokensSearchBox.text)
|
return symbol.startsWith(tokensSearchBox.text.toUpperCase()) || name.toUpperCase().startsWith(tokensSearchBox.text.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
|
||||||
return symbol.startsWith(tokensSearchBox.text.toUpperCase()) || name.toUpperCase().startsWith(tokensSearchBox.text.toUpperCase()) || (tokenSymbolByAddress!=="" && symbol.startsWith(tokenSymbolByAddress))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate: ActivityTypeCheckBox {
|
}
|
||||||
Layout.fillWidth: true
|
delegate: ActivityTypeCheckBox {
|
||||||
Layout.preferredHeight: 44
|
width: ListView.view.width
|
||||||
title: model.name
|
height: 44
|
||||||
titleAsideText: model.symbol
|
title: model.name
|
||||||
assetSettings.name: model.symbol ? Constants.tokenIcon(symbol) : ""
|
titleAsideText: model.symbol
|
||||||
assetSettings.isImage: true
|
assetSettings.name: model.symbol ? Constants.tokenIcon(symbol) : ""
|
||||||
buttonGroup: tokenButtonGroup
|
assetSettings.isImage: true
|
||||||
allChecked: root.allTokensChecked
|
buttonGroup: tokenButtonGroup
|
||||||
checked: root.allTokensChecked || root.tokensFilter.includes(model.symbol)
|
allChecked: root.allTokensChecked
|
||||||
onActionTriggered: root.tokenToggled(model.symbol)
|
checked: root.allTokensChecked || root.tokensFilter.includes(model.symbol)
|
||||||
}
|
onActionTriggered: root.tokenToggled(model.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,6 +128,12 @@ StatusMenu {
|
||||||
exclusive: false
|
exclusive: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("No Collectibles")
|
||||||
|
visible: root.collectiblesList.count === 0
|
||||||
|
}
|
||||||
|
|
||||||
SearchBox {
|
SearchBox {
|
||||||
id: collectiblesSearchBox
|
id: collectiblesSearchBox
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
@ -131,35 +142,34 @@ StatusMenu {
|
||||||
placeholderText: qsTr("Search collectible name")
|
placeholderText: qsTr("Search collectible name")
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
StatusListView {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
height: root.height - tabBar.height - tokensSearchBox.height - 12
|
||||||
spacing: 0
|
spacing: 0
|
||||||
Repeater {
|
model: SortFilterProxyModel {
|
||||||
model: SortFilterProxyModel {
|
sourceModel: root.collectiblesList
|
||||||
sourceModel: root.collectiblesList
|
filters: ExpressionFilter {
|
||||||
filters: ExpressionFilter {
|
enabled: root.collectiblesList.count > 0 && !!collectiblesSearchBox.text
|
||||||
enabled: root.collectiblesList.count > 0 && !!collectiblesSearchBox.text
|
expression: {
|
||||||
expression: {
|
let searchText = collectiblesSearchBox.text.toUpperCase()
|
||||||
let searchText = collectiblesSearchBox.text.toUpperCase()
|
return name.toUpperCase().startsWith(searchText)
|
||||||
return name.toUpperCase().startsWith(searchText)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate: ActivityTypeCheckBox {
|
}
|
||||||
Layout.fillWidth: true
|
delegate: ActivityTypeCheckBox {
|
||||||
Layout.preferredHeight: 44
|
width: ListView.view.width
|
||||||
title: model.name
|
height: 44
|
||||||
assetSettings.name: model.imageUrl
|
title: model.name
|
||||||
assetSettings.isImage: true
|
assetSettings.name: model.imageUrl
|
||||||
assetSettings.bgWidth: 32
|
assetSettings.isImage: true
|
||||||
assetSettings.bgHeight: 32
|
assetSettings.bgWidth: 32
|
||||||
assetSettings.bgRadius: assetSettings.bgHeight/2
|
assetSettings.bgHeight: 32
|
||||||
buttonGroup: collectibleButtonGroup
|
assetSettings.bgRadius: assetSettings.bgHeight/2
|
||||||
allChecked: root.allCollectiblesChecked
|
buttonGroup: collectibleButtonGroup
|
||||||
checked: root.allCollectiblesChecked || root.collectiblesFilter.includes(model.id)
|
allChecked: root.allCollectiblesChecked
|
||||||
onActionTriggered: root.collectibleToggled(model.id)
|
checked: root.allCollectiblesChecked || root.collectiblesFilter.includes(model.id)
|
||||||
loading: d.isFetching
|
onActionTriggered: root.collectibleToggled(model.id)
|
||||||
}
|
loading: d.isFetching
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,10 @@ import utils 1.0
|
||||||
QtObject {
|
QtObject {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property var transactionsList: walletSection.activityController.model
|
||||||
|
|
||||||
property var activityController: walletSection.activityController
|
property var activityController: walletSection.activityController
|
||||||
property bool filtersSet: fromTimestamp !== 0 || toTimestamp !== 0 ||
|
property bool filtersSet: selectedTime !== Constants.TransactionTimePeriod.All ||
|
||||||
typeFilters.length !== 0 ||
|
typeFilters.length !== 0 ||
|
||||||
statusFilters.length !== 0 ||
|
statusFilters.length !== 0 ||
|
||||||
tokensFilter.length !== 0 ||
|
tokensFilter.length !== 0 ||
|
||||||
|
@ -22,40 +24,58 @@ QtObject {
|
||||||
property double toTimestamp: new Date().valueOf()
|
property double toTimestamp: new Date().valueOf()
|
||||||
function setSelectedTimestamp(selcTime) {
|
function setSelectedTimestamp(selcTime) {
|
||||||
selectedTime = selcTime
|
selectedTime = selcTime
|
||||||
var currDate = new Date() // current date
|
|
||||||
switch(selectedTime) {
|
switch(selectedTime) {
|
||||||
case Constants.TransactionTimePeriod.All:
|
case Constants.TransactionTimePeriod.All:
|
||||||
fromTimestamp = 0
|
fromTimestamp = 0
|
||||||
toTimestamp = 0
|
toTimestamp = 0
|
||||||
break
|
break
|
||||||
case Constants.TransactionTimePeriod.Today:
|
case Constants.TransactionTimePeriod.Today:
|
||||||
fromTimestamp = currDate.valueOf() // Today
|
let dt = new Date()
|
||||||
toTimestamp = fromTimestamp
|
fromTimestamp = dt.setHours(0,0,0,0).valueOf() // Today
|
||||||
|
dt.setDate(dt.getDate() + 1) // next day...
|
||||||
|
dt.setHours(0, 0, 0, -1) // ... but just 1ms before midnight -> whole day included
|
||||||
|
toTimestamp = dt.valueOf()
|
||||||
break
|
break
|
||||||
case Constants.TransactionTimePeriod.Yesterday:
|
case Constants.TransactionTimePeriod.Yesterday:
|
||||||
fromTimestamp = new Date().setDate(currDate.getDate() - 1).valueOf() // Yesterday
|
let dt1 = new Date()
|
||||||
toTimestamp = fromTimestamp
|
dt1.setDate(dt1.getDate() - 1)
|
||||||
|
dt1.setHours(0, 0, 0, 0)
|
||||||
|
fromTimestamp = dt1.valueOf() // Yesterday
|
||||||
|
dt1.setDate(dt1.getDate() + 1)
|
||||||
|
dt1.setHours(0, 0, 0, -1)
|
||||||
|
toTimestamp = dt1.valueOf()
|
||||||
break
|
break
|
||||||
case Constants.TransactionTimePeriod.ThisWeek:
|
case Constants.TransactionTimePeriod.ThisWeek:
|
||||||
var firstDayOfCurrentWeek = currDate.getDate() - currDate.getDay()
|
let dt2 = new Date()
|
||||||
fromTimestamp = new Date().setDate(firstDayOfCurrentWeek).valueOf() // This week
|
let firstDayOfCurrentWeek = dt2.getDate() - dt2.getDay()
|
||||||
toTimestamp = currDate.valueOf()
|
dt2.setDate(firstDayOfCurrentWeek)
|
||||||
|
dt2.setHours(0, 0, 0, 0)
|
||||||
|
fromTimestamp = dt2.valueOf() // This week
|
||||||
|
toTimestamp = new Date().valueOf()
|
||||||
break
|
break
|
||||||
case Constants.TransactionTimePeriod.LastWeek:
|
case Constants.TransactionTimePeriod.LastWeek:
|
||||||
fromTimestamp = new Date().setDate(currDate.getDate() - 7).valueOf() // Last week
|
let dt3 = new Date()
|
||||||
toTimestamp = currDate.valueOf()
|
dt3.setDate(dt3.getDate() - 7)
|
||||||
|
dt3.setHours(0, 0, 0, 0)
|
||||||
|
fromTimestamp = dt3.valueOf() // Last week
|
||||||
|
toTimestamp = new Date().valueOf()
|
||||||
break
|
break
|
||||||
case Constants.TransactionTimePeriod.ThisMonth:
|
case Constants.TransactionTimePeriod.ThisMonth:
|
||||||
fromTimestamp = new Date().setDate(1).valueOf() // This month
|
let dt4 = new Date()
|
||||||
toTimestamp = currDate.valueOf()
|
dt4.setDate(1)
|
||||||
|
dt4.setHours(0, 0, 0, 0)
|
||||||
|
fromTimestamp = dt4.valueOf() // This month
|
||||||
|
toTimestamp = new Date().valueOf()
|
||||||
break
|
break
|
||||||
case Constants.TransactionTimePeriod.LastMonth:
|
case Constants.TransactionTimePeriod.LastMonth:
|
||||||
let x = new Date()
|
let dt5 = new Date()
|
||||||
x.setDate(1)
|
dt5.setDate(1)
|
||||||
x.setMonth(x.getMonth()-1)
|
dt5.setMonth(dt5.getMonth()-1)
|
||||||
fromTimestamp = x.valueOf() // Last month
|
dt5.setHours(0, 0, 0, 0)
|
||||||
x.setDate(new Date(x.getFullYear(), x.getMonth(), 0).getDate() + 1)
|
fromTimestamp = dt5.valueOf() // Last month
|
||||||
toTimestamp = x.valueOf()
|
dt5.setDate(new Date(dt5.getFullYear(), dt5.getMonth(), 0).getDate() + 2)
|
||||||
|
dt5.setHours(0, 0, 0, -1)
|
||||||
|
toTimestamp = dt5.valueOf()
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
|
@ -115,13 +135,14 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// To-do get correct model unaffected by filters from go side
|
property var recentsList: activityController.recipientsModel
|
||||||
property var recentsList: []
|
|
||||||
property var recentsFilters: []
|
property var recentsFilters: []
|
||||||
|
function updateRecipientsModel() {
|
||||||
|
activityController.updateRecipientsModel()
|
||||||
|
}
|
||||||
function toggleRecents(address) {
|
function toggleRecents(address) {
|
||||||
// update filters
|
// update filters
|
||||||
recentsFilters = toggleFilterState(recentsFilters, address, recentsList.count)
|
recentsFilters = toggleFilterState(recentsFilters, address, recentsList.count)
|
||||||
// Set backend values
|
|
||||||
activityController.setFilterToAddresses(JSON.stringify(recentsFilters.concat(savedAddressFilters)))
|
activityController.setFilterToAddresses(JSON.stringify(recentsFilters.concat(savedAddressFilters)))
|
||||||
activityController.updateFilter()
|
activityController.updateFilter()
|
||||||
}
|
}
|
||||||
|
@ -176,4 +197,29 @@ QtObject {
|
||||||
function updateFilterBase() {
|
function updateFilterBase() {
|
||||||
activityController.updateFilterBase()
|
activityController.updateFilterBase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetAllFilters() {
|
||||||
|
selectedTime = Constants.TransactionTimePeriod.All
|
||||||
|
fromTimestamp = activityController.startTimestamp * 1000
|
||||||
|
toTimestamp = new Date().valueOf()
|
||||||
|
activityController.setFilterTime(fromTimestamp/1000, toTimestamp/1000)
|
||||||
|
|
||||||
|
typeFilters = []
|
||||||
|
activityController.setFilterType(JSON.stringify(typeFilters))
|
||||||
|
|
||||||
|
statusFilters = []
|
||||||
|
activityController.setFilterStatus(JSON.stringify(statusFilters))
|
||||||
|
|
||||||
|
tokensFilter = []
|
||||||
|
activityController.setFilterAssets(JSON.stringify(tokensFilter), false)
|
||||||
|
|
||||||
|
collectiblesFilter = []
|
||||||
|
// To-do call update filter for collectibles
|
||||||
|
|
||||||
|
recentsFilters = []
|
||||||
|
savedAddressFilters = []
|
||||||
|
activityController.setFilterToAddresses(JSON.stringify(recentsFilters.concat(savedAddressFilters)))
|
||||||
|
|
||||||
|
activityController.updateFilter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,14 +64,13 @@ ColumnLayout {
|
||||||
text: qsTr("Activity for this account will appear here")
|
text: qsTr("Activity for this account will appear here")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tp-do make connections with nim once logic is ready
|
|
||||||
ActivityFilterPanel {
|
ActivityFilterPanel {
|
||||||
id: filterComponent
|
id: filterComponent
|
||||||
visible: !d.isLoading && (transactionListRoot.count !== 0 || d.activityFiltersStore.filtersSet)
|
visible: !d.isLoading && (transactionListRoot.count !== 0 || d.activityFiltersStore.filtersSet)
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 50
|
|
||||||
activityFilterStore: d.activityFiltersStore
|
activityFilterStore: d.activityFiltersStore
|
||||||
store: WalletStores.RootStore
|
store: WalletStores.RootStore
|
||||||
|
isLoading: d.isLoading
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
Loading…
Reference in New Issue