parent
ba89daa737
commit
a1e1e316db
|
@ -34,8 +34,7 @@ SplitView {
|
||||||
sourceModel: tokenHoldersModel
|
sourceModel: tokenHoldersModel
|
||||||
|
|
||||||
sortBy: holdersList.sortBy
|
sortBy: holdersList.sortBy
|
||||||
sortOrder: holdersList.sorting === SortableTokenHoldersList.Sorting.Descending
|
sortOrder: holdersList.sortOrder ? Qt.DescendingOrder : Qt.AscendingOrder
|
||||||
? Qt.DescendingOrder : Qt.AscendingOrder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: logs.logEvent("holdersList.clicked: " + index)
|
onClicked: logs.logEvent("holdersList.clicked: " + index)
|
||||||
|
|
|
@ -20,10 +20,10 @@ SplitView {
|
||||||
Item {
|
Item {
|
||||||
SplitView.fillWidth: true
|
SplitView.fillWidth: true
|
||||||
SplitView.fillHeight: true
|
SplitView.fillHeight: true
|
||||||
|
|
||||||
TokenHoldersPanel {
|
TokenHoldersPanel {
|
||||||
anchors.centerIn: parent
|
|
||||||
width: 568
|
width: 568
|
||||||
|
height: 364
|
||||||
|
anchors.centerIn: parent
|
||||||
tokenName: "Aniversary"
|
tokenName: "Aniversary"
|
||||||
model: TokenHoldersModel {}
|
model: TokenHoldersModel {}
|
||||||
isSelectorMode: editorSelectorMode.checked
|
isSelectorMode: editorSelectorMode.checked
|
||||||
|
|
|
@ -33,7 +33,7 @@ ListModel {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
walletAddress: "0xb794f5ea0ba39494ce839613fffba74279579268",
|
walletAddress: "0xb794f5ea0ba394782634hhh3fffba74279579264",
|
||||||
imageSource: "",
|
imageSource: "",
|
||||||
amount: 1,
|
amount: 1,
|
||||||
noOfMessages: 0,
|
noOfMessages: 0,
|
||||||
|
@ -41,7 +41,7 @@ ListModel {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
walletAddress: "0xc794f5ea0ba39494ce839613fffba74279579268",
|
walletAddress: "0xc794f577990jjjjjewaofherfffba74279579265",
|
||||||
imageSource: "",
|
imageSource: "",
|
||||||
amount: 11,
|
amount: 11,
|
||||||
noOfMessages: 0,
|
noOfMessages: 0,
|
||||||
|
@ -49,7 +49,7 @@ ListModel {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
walletAddress: "0xd794f5ea0ba39494ce839613fffba74279579268",
|
walletAddress: "0xd794f5ea009fnrsehggwe7777ffba74279579266",
|
||||||
imageSource: "",
|
imageSource: "",
|
||||||
amount: 14,
|
amount: 14,
|
||||||
noOfMessages: 0,
|
noOfMessages: 0,
|
||||||
|
|
|
@ -20,16 +20,8 @@ import utils 1.0
|
||||||
StatusListView {
|
StatusListView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
enum SortBy {
|
|
||||||
None, Username, NoOfMessages, Holding
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Sorting {
|
|
||||||
Descending, Ascending
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property alias sortBy: d.sortBy
|
readonly property alias sortBy: d.sortBy
|
||||||
readonly property alias sorting: d.sorting
|
readonly property alias sortOrder: d.sorting
|
||||||
|
|
||||||
signal clicked(int index, var parent, var mouse)
|
signal clicked(int index, var parent, var mouse)
|
||||||
|
|
||||||
|
@ -55,9 +47,9 @@ StatusListView {
|
||||||
d.resetOtherHeaders(this)
|
d.resetOtherHeaders(this)
|
||||||
|
|
||||||
if (sorting === StatusSortableColumnHeader.Sorting.Ascending)
|
if (sorting === StatusSortableColumnHeader.Sorting.Ascending)
|
||||||
d.sorting = SortableTokenHoldersList.Sorting.Ascending
|
d.sorting = Qt.AscendingOrder
|
||||||
else if (sorting === StatusSortableColumnHeader.Sorting.Descending)
|
else if (sorting === StatusSortableColumnHeader.Sorting.Descending)
|
||||||
d.sorting = SortableTokenHoldersList.Sorting.Descending
|
d.sorting = Qt.DescendingOrder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +67,8 @@ StatusListView {
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
property int sortBy: SortableTokenHoldersList.SortBy.None
|
property int sortBy: TokenHoldersProxyModel.SortBy.None
|
||||||
property int sorting: SortableTokenHoldersList.Sorting.Descending
|
property int sorting: Qt.DescendingOrder
|
||||||
|
|
||||||
readonly property int red2Color: 4
|
readonly property int red2Color: 4
|
||||||
|
|
||||||
|
@ -113,9 +105,9 @@ StatusListView {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
||||||
d.sortBy = SortableTokenHoldersList.SortBy.Username
|
d.sortBy = TokenHoldersProxyModel.SortBy.Username
|
||||||
else
|
else
|
||||||
d.sortBy = SortableTokenHoldersList.SortBy.None
|
d.sortBy = TokenHoldersProxyModel.SortBy.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,9 +123,9 @@ StatusListView {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
||||||
d.sortBy = SortableTokenHoldersList.SortBy.NoOfMessages
|
d.sortBy = TokenHoldersProxyModel.SortBy.NoOfMessages
|
||||||
else
|
else
|
||||||
d.sortBy = SortableTokenHoldersList.SortBy.None
|
d.sortBy = TokenHoldersProxyModel.SortBy.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,9 +141,9 @@ StatusListView {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
||||||
d.sortBy = SortableTokenHoldersList.SortBy.Holding
|
d.sortBy = TokenHoldersProxyModel.SortBy.Holding
|
||||||
else
|
else
|
||||||
d.sortBy = SortableTokenHoldersList.SortBy.None
|
d.sortBy = TokenHoldersProxyModel.SortBy.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +177,7 @@ StatusListView {
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property bool showSeparator: isFirstRowAddress
|
readonly property bool showSeparator: isFirstRowAddress
|
||||||
&& root.sortBy === SortableTokenHoldersList.SortBy.Username
|
&& root.sortBy === TokenHoldersProxyModel.SortBy.Username
|
||||||
|
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ Control {
|
||||||
property alias isAirdropEnabled: infoBoxPanel.buttonEnabled
|
property alias isAirdropEnabled: infoBoxPanel.buttonEnabled
|
||||||
|
|
||||||
readonly property alias sortBy: holdersList.sortBy
|
readonly property alias sortBy: holdersList.sortBy
|
||||||
readonly property alias sorting: holdersList.sorting
|
readonly property alias sorting: holdersList.sortOrder
|
||||||
|
|
||||||
readonly property bool empty: countCheckHelper.count === 0
|
readonly property bool empty: countCheckHelper.count === 0
|
||||||
|
|
||||||
|
@ -50,8 +50,7 @@ Control {
|
||||||
searchText: searcher.text
|
searchText: searcher.text
|
||||||
|
|
||||||
sortBy: holdersList.sortBy
|
sortBy: holdersList.sortBy
|
||||||
sortOrder: holdersList.sorting === SortableTokenHoldersList.Sorting.Descending
|
sortOrder: holdersList.sortOrder ? Qt.DescendingOrder : Qt.AscendingOrder
|
||||||
? Qt.DescendingOrder : Qt.AscendingOrder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
|
|
@ -0,0 +1,288 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
import shared.controls 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype TokenHoldersList
|
||||||
|
\inherits StatusListView
|
||||||
|
\brief Shows list of users or addresses with corrensponding numbers of
|
||||||
|
messages and holding amounts.
|
||||||
|
|
||||||
|
Expected roles: name, walletAddress, imageSource, amount
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
implicitHeight: (listView.contentHeight+header.height+12)//initial height plus top margin
|
||||||
|
|
||||||
|
property alias model: listView.model
|
||||||
|
property bool isSelectorMode: false
|
||||||
|
readonly property alias sortBy: d.sortBy
|
||||||
|
readonly property alias sortOrder: d.sorting
|
||||||
|
readonly property bool bottomSeparatorVisible: ((listView.contentY > 0) &&
|
||||||
|
(listView.contentY < (listView.contentHeight - listView.height - 40/*margins*/)))
|
||||||
|
|
||||||
|
signal selfDestructAmountChanged(string walletAddress, int amount)
|
||||||
|
signal selfDestructRemoved(string walletAddress)
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
property int sortBy: TokenHoldersProxyModel.SortBy.None
|
||||||
|
property int sorting: Qt.DescendingOrder
|
||||||
|
property var selectedTokenAmount: new Map();
|
||||||
|
property var selectedTokenChecked: new Map();
|
||||||
|
property int delegateHeight: 64
|
||||||
|
|
||||||
|
signal resetOtherHeaders(var header)
|
||||||
|
}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: header
|
||||||
|
width: parent.width
|
||||||
|
height: 40
|
||||||
|
readonly property alias usernameHeaderWidth: usernameHeader.width
|
||||||
|
readonly property alias holdingHeaderWidth: holdingHeader.width
|
||||||
|
background: Rectangle {
|
||||||
|
id: scrollingSeparator
|
||||||
|
width: parent.width
|
||||||
|
height: 4
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
color: Theme.palette.baseColor2
|
||||||
|
visible: (listView.contentY > 0)
|
||||||
|
}
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
clip: true
|
||||||
|
RowLayout {
|
||||||
|
id: row
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Style.current.padding
|
||||||
|
RowLayout {
|
||||||
|
id: usernameHeader
|
||||||
|
|
||||||
|
ColumnHeader {
|
||||||
|
text: qsTr("Username")
|
||||||
|
|
||||||
|
traversalOrder: [
|
||||||
|
StatusSortableColumnHeader.Sorting.NoSorting,
|
||||||
|
StatusSortableColumnHeader.Sorting.Ascending,
|
||||||
|
StatusSortableColumnHeader.Sorting.Descending
|
||||||
|
]
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
||||||
|
d.sortBy = TokenHoldersProxyModel.SortBy.Username
|
||||||
|
else
|
||||||
|
d.sortBy = TokenHoldersProxyModel.SortBy.None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnHeader {
|
||||||
|
id: holdingHeader
|
||||||
|
text: qsTr("Hodling")
|
||||||
|
onClicked: {
|
||||||
|
if (sorting !== StatusSortableColumnHeader.Sorting.NoSorting)
|
||||||
|
d.sortBy = TokenHoldersProxyModel.SortBy.Holding
|
||||||
|
else
|
||||||
|
d.sortBy = TokenHoldersProxyModel.SortBy.None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.preferredWidth: 233
|
||||||
|
Layout.rightMargin: Style.current.halfPadding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusListView {
|
||||||
|
id: listView
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: header.height
|
||||||
|
currentIndex: -1
|
||||||
|
component ColumnHeader: StatusSortableColumnHeader {
|
||||||
|
id: columnHeader
|
||||||
|
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
Connections {
|
||||||
|
target: d
|
||||||
|
|
||||||
|
function onResetOtherHeaders(header) {
|
||||||
|
if (header !== columnHeader)
|
||||||
|
columnHeader.reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
d.resetOtherHeaders(this)
|
||||||
|
|
||||||
|
if (sorting === StatusSortableColumnHeader.Sorting.Ascending)
|
||||||
|
d.sorting = Qt.AscendingOrder
|
||||||
|
else if (sorting === StatusSortableColumnHeader.Sorting.Descending)
|
||||||
|
d.sorting = Qt.DescendingOrder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component NumberCell: StatusBaseText {
|
||||||
|
horizontalAlignment: Qt.AlignRight
|
||||||
|
|
||||||
|
font.weight: Font.Medium
|
||||||
|
font.pixelSize: 13
|
||||||
|
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
elide: Qt.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
id: delegate
|
||||||
|
width: ListView.view.width
|
||||||
|
height: d.delegateHeight
|
||||||
|
padding: 0
|
||||||
|
readonly property string name: model.name
|
||||||
|
|
||||||
|
readonly property bool isFirstRowAddress: {
|
||||||
|
if (model.name !== "")
|
||||||
|
return false
|
||||||
|
|
||||||
|
const item = listView.itemAtIndex(index - 1)
|
||||||
|
return item && item.name
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool showSeparator: isFirstRowAddress
|
||||||
|
&& root.sortBy === TokenHoldersProxyModel.SortBy.Username
|
||||||
|
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Style.current.radius
|
||||||
|
color: (delegate.hovered || delegate.ListView.isCurrentItem)
|
||||||
|
? Theme.palette.baseColor2 : "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: delegate.showSeparator
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: delegate.topPadding / 2
|
||||||
|
|
||||||
|
height: 1
|
||||||
|
color: Theme.palette.baseColor2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
RowLayout {
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
|
|
||||||
|
StatusListItem {
|
||||||
|
readonly property bool unknownHolder: model.name === ""
|
||||||
|
readonly property string formattedTitle: unknownHolder ? "?" : model.name
|
||||||
|
Layout.preferredWidth: header.usernameHeaderWidth
|
||||||
|
color: "transparent"
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
sensor.enabled: false
|
||||||
|
title: formattedTitle
|
||||||
|
statusListItemTitle.visible: !unknownHolder
|
||||||
|
subTitle: Utils.getElidedPk(model.walletAddress)
|
||||||
|
asset.name: model.imageSource
|
||||||
|
asset.isImage: true
|
||||||
|
asset.isLetterIdenticon: !asset.name
|
||||||
|
asset.color: Theme.palette.getColor("red2")
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberCell {
|
||||||
|
Layout.preferredWidth: header.holdingHeaderWidth
|
||||||
|
Layout.leftMargin: Style.current.halfPadding
|
||||||
|
|
||||||
|
text: LocaleUtils.numberToLocaleString(model.amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.preferredWidth: 100 }
|
||||||
|
|
||||||
|
StatusComboBox {
|
||||||
|
id: combo
|
||||||
|
Layout.preferredWidth: 68
|
||||||
|
Layout.preferredHeight: 44
|
||||||
|
control.spacing: Style.current.halfPadding / 2
|
||||||
|
model: amount
|
||||||
|
size: StatusComboBox.Size.Small
|
||||||
|
type: StatusComboBox.Type.Secondary
|
||||||
|
delegate: StatusItemDelegate {
|
||||||
|
width: combo.control.width
|
||||||
|
centerTextHorizontally: true
|
||||||
|
highlighted: combo.control.highlightedIndex === index
|
||||||
|
font: combo.control.font
|
||||||
|
text: Number(modelData) + 1
|
||||||
|
}
|
||||||
|
contentItem: StatusBaseText {
|
||||||
|
id: comboText
|
||||||
|
font: combo.control.font
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (d.selectedTokenAmount.get(walletAddress) === undefined) {
|
||||||
|
d.selectedTokenAmount.set(walletAddress, amount);
|
||||||
|
}
|
||||||
|
text = d.selectedTokenAmount.get(walletAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
control.onActivated: {
|
||||||
|
d.selectedTokenAmount.set(walletAddress, (index+1));
|
||||||
|
comboText.text = d.selectedTokenAmount.get(walletAddress);
|
||||||
|
if (checkBox.checked) {
|
||||||
|
root.selfDestructAmountChanged(walletAddress, d.selectedTokenAmount.get(walletAddress))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item { Layout.preferredWidth: 28 }
|
||||||
|
StatusCheckBox {
|
||||||
|
id: checkBox
|
||||||
|
Layout.preferredWidth: 24
|
||||||
|
Layout.preferredHeight: 24
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
visible: root.isSelectorMode
|
||||||
|
padding: 0
|
||||||
|
onCheckStateChanged: {
|
||||||
|
if (checked)
|
||||||
|
root.selfDestructAmountChanged(model.walletAddress, d.selectedTokenAmount.get(walletAddress))
|
||||||
|
else
|
||||||
|
root.selfDestructRemoved(model.walletAddress)
|
||||||
|
|
||||||
|
d.selectedTokenChecked.set(walletAddress, checked);
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
checked = !!d.selectedTokenChecked.get(walletAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,165 +1,97 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.15
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.15
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.15
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Core.Utils 0.1
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Popups 0.1
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
|
|
||||||
Control {
|
Control {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Expected roles: name, walletAddress, imageSource, amount
|
|
||||||
property var model
|
property var model
|
||||||
|
|
||||||
property string tokenName
|
property string tokenName
|
||||||
property bool isSelectorMode: false
|
property bool isSelectorMode: false
|
||||||
|
|
||||||
signal selfDestructAmountChanged(string walletAddress, int amount)
|
signal selfDestructAmountChanged(string walletAddress, int amount)
|
||||||
signal selfDestructRemoved(string walletAddress)
|
signal selfDestructRemoved(string walletAddress)
|
||||||
|
bottomPadding: 16
|
||||||
|
|
||||||
QtObject {
|
TokenHoldersProxyModel {
|
||||||
id: d
|
id: filteredModel
|
||||||
|
sourceModel: root.model
|
||||||
|
searchText: searcher.text
|
||||||
|
|
||||||
readonly property int red2Color: 4
|
sortBy: holdersList.sortBy
|
||||||
|
sortOrder: holdersList.sortOrder ? Qt.DescendingOrder : Qt.AscendingOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
spacing: Style.current.padding
|
id: column
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: Style.current.padding
|
||||||
|
spacing: 0
|
||||||
|
StatusBaseText {
|
||||||
|
id: txtLabel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: Style.current.padding
|
||||||
|
Layout.rightMargin: Style.current.padding
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
|
||||||
SortFilterProxyModel {
|
text: qsTr("%1 token holders").arg(root.tokenName)
|
||||||
id: filteredModel
|
|
||||||
|
|
||||||
sourceModel: root.model
|
|
||||||
filters: ExpressionFilter {
|
|
||||||
enabled: searcher.enabled
|
|
||||||
expression: {
|
|
||||||
searcher.text
|
|
||||||
return model.name.toLowerCase().includes(searcher.text.toLowerCase()) ||
|
|
||||||
model.walletAddress.toLowerCase().includes(searcher.text.toLowerCase())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchBox {
|
SearchBox {
|
||||||
id: searcher
|
id: searcher
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 12
|
||||||
|
Layout.leftMargin: Style.current.padding
|
||||||
|
Layout.rightMargin: Style.current.padding
|
||||||
|
visible: !root.empty
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
minimumHeight: 36 // by design
|
minimumHeight: 36 // by design
|
||||||
maximumHeight: minimumHeight
|
maximumHeight: minimumHeight
|
||||||
enabled: root.model && root.model.count > 0
|
placeholderText: qsTr("Search hodlers")
|
||||||
placeholderText: enabled ? qsTr("Search") : qsTr("No placeholders to search")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
id: anotherLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 12
|
||||||
|
Layout.leftMargin: Style.current.padding
|
||||||
|
Layout.rightMargin: Style.current.padding
|
||||||
|
|
||||||
visible: !root.preview
|
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
font.pixelSize: Style.current.primaryTextFontSize
|
font.pixelSize: Style.current.primaryTextFontSize
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
text: searcher.text.length > 0 ? qsTr("Search results") : qsTr("All %1 token holders").arg(root.tokenName)
|
visible: (searcher.text.length > 0 && filteredModel.count === 0)
|
||||||
|
text: visible ? qsTr("No hodlers found") : ""
|
||||||
}
|
}
|
||||||
|
TokenHoldersList {
|
||||||
Item {
|
id: holdersList
|
||||||
id: scrollViewWrapper
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
implicitWidth: scrollView.implicitWidth
|
Layout.topMargin: 12
|
||||||
implicitHeight: scrollView.implicitHeight
|
isSelectorMode: root.isSelectorMode
|
||||||
|
model: filteredModel
|
||||||
StatusListView {
|
onSelfDestructRemoved: {
|
||||||
id: scrollView
|
root.selfDestructRemoved(walletAddress);
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
implicitHeight: contentHeight
|
|
||||||
|
|
||||||
model: filteredModel
|
|
||||||
|
|
||||||
ScrollBar.vertical: StatusScrollBar {
|
|
||||||
parent: scrollViewWrapper
|
|
||||||
anchors.top: scrollView.top
|
|
||||||
anchors.bottom: scrollView.bottom
|
|
||||||
anchors.left: scrollView.right
|
|
||||||
anchors.leftMargin: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: RowLayout {
|
|
||||||
width: ListView.view.width
|
|
||||||
spacing: Style.current.padding
|
|
||||||
|
|
||||||
StatusListItem {
|
|
||||||
readonly property bool unknownHolder: model.name === ""
|
|
||||||
readonly property string formattedTitle: unknownHolder ? "?" : model.name
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
sensor.enabled: false
|
|
||||||
title: formattedTitle
|
|
||||||
statusListItemTitle.visible: !unknownHolder
|
|
||||||
subTitle: model.walletAddress
|
|
||||||
asset.name: model.imageSource
|
|
||||||
asset.isImage: true
|
|
||||||
asset.isLetterIdenticon: unknownHolder
|
|
||||||
asset.color: Theme.palette.userCustomizationColors[d.red2Color]
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusComboBox {
|
|
||||||
id: combo
|
|
||||||
Layout.preferredWidth: 88
|
|
||||||
Layout.preferredHeight: 44
|
|
||||||
visible: root.isSelectorMode && amount > 1
|
|
||||||
control.spacing: Style.current.halfPadding / 2
|
|
||||||
model: amount
|
|
||||||
size: StatusComboBox.Size.Small
|
|
||||||
type: StatusComboBox.Type.Secondary
|
|
||||||
delegate: StatusItemDelegate {
|
|
||||||
width: combo.control.width
|
|
||||||
centerTextHorizontally: true
|
|
||||||
highlighted: combo.control.highlightedIndex === index
|
|
||||||
font: combo.control.font
|
|
||||||
text: Number(modelData) + 1
|
|
||||||
}
|
|
||||||
contentItem: StatusBaseText {
|
|
||||||
font: combo.control.font
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
text: Number(combo.control.displayText) + 1
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
control.onDisplayTextChanged: {
|
|
||||||
if(checkBox.checked)
|
|
||||||
root.selfDestructAmountChanged(walletAddress, Number(combo.currentIndex) + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusCheckBox {
|
|
||||||
id: checkBox
|
|
||||||
|
|
||||||
Layout.leftMargin: Style.current.padding
|
|
||||||
visible: root.isSelectorMode
|
|
||||||
padding: 0
|
|
||||||
onCheckStateChanged: {
|
|
||||||
if(checked)
|
|
||||||
root.selfDestructAmountChanged(model.walletAddress, Number(combo.currentIndex) + 1)
|
|
||||||
else
|
|
||||||
root.selfDestructRemoved(model.walletAddress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
onSelfDestructAmountChanged: {
|
||||||
|
root.selfDestructAmountChanged(walletAddress, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 4
|
||||||
|
Layout.alignment: Qt.AlignBottom
|
||||||
|
color: Theme.palette.baseColor2
|
||||||
|
opacity: holdersList.bottomSeparatorVisible ? 1.0 : 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,13 @@ SortFilterProxyModel {
|
||||||
property string searchText
|
property string searchText
|
||||||
readonly property string searchTextLowerCase: searchText.toLowerCase()
|
readonly property string searchTextLowerCase: searchText.toLowerCase()
|
||||||
|
|
||||||
property int sortBy: SortableTokenHoldersList.SortBy.Username
|
property int sortBy: TokenHoldersProxyModel.SortBy.Username
|
||||||
property int sortOrder: Qt.AscendingOrder
|
property int sortOrder: Qt.AscendingOrder
|
||||||
|
|
||||||
|
enum SortBy {
|
||||||
|
None, Username, NoOfMessages, Holding
|
||||||
|
}
|
||||||
|
|
||||||
filters: ExpressionFilter {
|
filters: ExpressionFilter {
|
||||||
expression: {
|
expression: {
|
||||||
root.searchTextLowerCase
|
root.searchTextLowerCase
|
||||||
|
@ -23,7 +27,7 @@ SortFilterProxyModel {
|
||||||
|
|
||||||
sorters: [
|
sorters: [
|
||||||
FilterSorter {
|
FilterSorter {
|
||||||
enabled: root.sortBy === SortableTokenHoldersList.SortBy.Username
|
enabled: root.sortBy === TokenHoldersProxyModel.SortBy.Username
|
||||||
|
|
||||||
ValueFilter {
|
ValueFilter {
|
||||||
roleName: "name"
|
roleName: "name"
|
||||||
|
@ -35,27 +39,27 @@ SortFilterProxyModel {
|
||||||
},
|
},
|
||||||
|
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
enabled: root.sortBy === SortableTokenHoldersList.SortBy.Username
|
enabled: root.sortBy === TokenHoldersProxyModel.SortBy.Username
|
||||||
roleName: "name"
|
roleName: "name"
|
||||||
sortOrder: root.sortOrder
|
sortOrder: root.sortOrder
|
||||||
priority: 2
|
priority: 2
|
||||||
},
|
},
|
||||||
|
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
enabled: root.sortBy === SortableTokenHoldersList.SortBy.Username
|
enabled: root.sortBy === TokenHoldersProxyModel.SortBy.Username
|
||||||
roleName: "walletAddress"
|
roleName: "walletAddress"
|
||||||
sortOrder: root.sortOrder
|
sortOrder: root.sortOrder
|
||||||
priority: 1
|
priority: 1
|
||||||
},
|
},
|
||||||
|
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
enabled: root.sortBy === SortableTokenHoldersList.SortBy.NoOfMessages
|
enabled: root.sortBy === TokenHoldersProxyModel.SortBy.NoOfMessages
|
||||||
roleName: "noOfMessages"
|
roleName: "noOfMessages"
|
||||||
sortOrder: root.sortOrder
|
sortOrder: root.sortOrder
|
||||||
},
|
},
|
||||||
|
|
||||||
RoleSorter {
|
RoleSorter {
|
||||||
enabled: root.sortBy === SortableTokenHoldersList.SortBy.Holding
|
enabled: root.sortBy === TokenHoldersProxyModel.SortBy.Holding
|
||||||
roleName: "amount"
|
roleName: "amount"
|
||||||
sortOrder: root.sortOrder
|
sortOrder: root.sortOrder
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,14 +63,10 @@ StatusDialog {
|
||||||
implicitWidth: 600 // by design
|
implicitWidth: 600 // by design
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
TokenHoldersPanel {
|
contentItem: TokenHoldersPanel {
|
||||||
id: tokenHoldersPanel
|
id: tokenHoldersPanel
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
padding: 16
|
|
||||||
tokenName: root.collectibleName
|
tokenName: root.collectibleName
|
||||||
isSelectorMode: true
|
isSelectorMode: true
|
||||||
|
|
||||||
onSelfDestructAmountChanged: d.updateTokensToDestruct(walletAddress, amount)
|
onSelfDestructAmountChanged: d.updateTokensToDestruct(walletAddress, amount)
|
||||||
onSelfDestructRemoved: d.clearTokensToDesctruct(walletAddress)
|
onSelfDestructRemoved: d.clearTokensToDesctruct(walletAddress)
|
||||||
}
|
}
|
||||||
|
@ -78,6 +74,12 @@ StatusDialog {
|
||||||
footer: StatusDialogFooter {
|
footer: StatusDialogFooter {
|
||||||
spacing: Style.current.padding
|
spacing: Style.current.padding
|
||||||
rightButtons: ObjectModel {
|
rightButtons: ObjectModel {
|
||||||
|
StatusFlatButton {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
onClicked: {
|
||||||
|
root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
StatusButton {
|
StatusButton {
|
||||||
enabled: d.tokenCount > 0
|
enabled: d.tokenCount > 0
|
||||||
text: qsTr("Remotely destruct %n token(s)", "", d.tokenCount)
|
text: qsTr("Remotely destruct %n token(s)", "", d.tokenCount)
|
||||||
|
|
Loading…
Reference in New Issue