feat(CommunityMintTokens): Using sortable list of tokens holders
New list contains also dropdown menu with some actions, basic integration is done for holder types and actions supported currently by the backend. Closes: #10621
This commit is contained in:
parent
99ad85047d
commit
8102600c5b
|
@ -33,6 +33,10 @@ SettingsPageLayout {
|
|||
d.selectCollectible(key, amount)
|
||||
}
|
||||
|
||||
function addAddresses(addresses) {
|
||||
d.addAddresses(addresses)
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
|
@ -43,6 +47,7 @@ SettingsPageLayout {
|
|||
readonly property string newAirdropViewPageTitle: qsTr("New airdrop")
|
||||
|
||||
signal selectCollectible(string key, int amount)
|
||||
signal addAddresses(var addresses)
|
||||
}
|
||||
|
||||
content: StackView {
|
||||
|
@ -110,7 +115,10 @@ SettingsPageLayout {
|
|||
}
|
||||
onNavigateToMintTokenSettings: root.navigateToMintTokenSettings()
|
||||
|
||||
Component.onCompleted: d.selectCollectible.connect(view.selectCollectible)
|
||||
Component.onCompleted: {
|
||||
d.selectCollectible.connect(view.selectCollectible)
|
||||
d.addAddresses.connect(view.addAddresses)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ SettingsPageLayout {
|
|||
signal burnCollectibles(string tokenKey,
|
||||
int amount)
|
||||
|
||||
signal airdropCollectible(string tokenKey)
|
||||
signal airdropCollectible(string tokenKey, var addresses)
|
||||
|
||||
signal deleteToken(string tokenKey)
|
||||
|
||||
|
@ -127,6 +127,7 @@ SettingsPageLayout {
|
|||
onInitialItemChanged: updateInitialStackView()
|
||||
|
||||
signal airdropClicked()
|
||||
signal remoteDestructAddressClicked(string address)
|
||||
|
||||
signal retryMintClicked()
|
||||
|
||||
|
@ -430,6 +431,7 @@ SettingsPageLayout {
|
|||
|
||||
collectibleName: root.title
|
||||
model: d.tokenOwnersModel
|
||||
destroyOnClose: false
|
||||
|
||||
onRemotelyDestructClicked: {
|
||||
d.selfDestructTokensList = selfDestructTokensList
|
||||
|
@ -443,6 +445,8 @@ SettingsPageLayout {
|
|||
|
||||
property int tokenCount
|
||||
|
||||
destroyOnClose: false
|
||||
|
||||
title: qsTr("Remotely destruct %n token(s)", "", tokenCount)
|
||||
acceptBtnText: qsTr("Remotely destruct")
|
||||
alertText: qsTr("Continuing will destroy tokens held by members and revoke any permissions they are given. To undo you will have to issue them new tokens.")
|
||||
|
@ -501,6 +505,15 @@ SettingsPageLayout {
|
|||
signTransactionPopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: d
|
||||
|
||||
function onRemoteDestructAddressClicked(address) {
|
||||
remotelyDestructPopup.open()
|
||||
// TODO: set the address selected in the popup's list
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -649,11 +662,24 @@ SettingsPageLayout {
|
|||
}
|
||||
}
|
||||
|
||||
onGeneralAirdropRequested: {
|
||||
root.airdropCollectible(view.symbol, [])
|
||||
}
|
||||
|
||||
onAirdropRequested: {
|
||||
root.airdropCollectible(view.symbol, [address])
|
||||
}
|
||||
|
||||
onRemoteDestructRequested: {
|
||||
d.remoteDestructAddressClicked(address)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: d
|
||||
|
||||
// handle airdrop request from the footer
|
||||
function onAirdropClicked() {
|
||||
root.airdropCollectible(view.symbol) // TODO: Backend. It should just be the key (hash(chainId + contractAddress)
|
||||
root.airdropCollectible(view.symbol, []) // TODO: Backend. It should just be the key (hash(chainId + contractAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,7 +342,9 @@ StatusSectionLayout {
|
|||
}
|
||||
onSignBurnTransactionOpened: communityTokensStore.computeBurnFee(chainId)
|
||||
onBurnCollectibles: communityTokensStore.burnCollectibles(tokenKey, amount)
|
||||
onAirdropCollectible: root.goTo(Constants.CommunitySettingsSections.Airdrops)
|
||||
onAirdropCollectible: {
|
||||
root.goTo(Constants.CommunitySettingsSections.Airdrops)
|
||||
}
|
||||
onDeleteToken: communityTokensStore.deleteToken(root.community.id, tokenKey)
|
||||
onRetryMintToken: communityTokensStore.retryMintToken(root.community.id, tokenKey)
|
||||
|
||||
|
@ -478,12 +480,15 @@ StatusSectionLayout {
|
|||
Connections {
|
||||
target: mintPanel
|
||||
|
||||
function onAirdropCollectible(key) {
|
||||
function onAirdropCollectible(key, addresses) {
|
||||
// Here it is forced a navigation to the new airdrop form, like if it was clicked the header button
|
||||
airdropPanel.primaryHeaderButtonClicked()
|
||||
|
||||
// Force a token selection to be airdroped with default amount 1
|
||||
airdropPanel.selectCollectible(key, 1)
|
||||
|
||||
// Set given addresses as recipients
|
||||
airdropPanel.addAddresses(addresses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,12 +510,15 @@ StatusSectionLayout {
|
|||
function goTo(section: int, subSection: int) {
|
||||
//find and enable section
|
||||
const matchingIndex = listView.model.findIndex((modelItem, index) => modelItem.id === section && modelItem.enabled)
|
||||
if(matchingIndex !== -1) {
|
||||
d.currentIndex = matchingIndex
|
||||
//find and enable subsection if subSection navigation is available
|
||||
if(d.currentItem && d.currentItem.goTo) {
|
||||
d.currentItem.goTo(subSection)
|
||||
}
|
||||
|
||||
if(matchingIndex === -1)
|
||||
return
|
||||
|
||||
d.currentIndex = matchingIndex
|
||||
|
||||
//find and enable subsection if subSection navigation is available
|
||||
if(d.currentItem && d.currentItem.goTo) {
|
||||
d.currentItem.goTo(subSection)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,10 @@ StatusScrollView {
|
|||
selectedHoldingsModel.append(entry)
|
||||
}
|
||||
|
||||
function addAddresses(_addresses) {
|
||||
addresses.addAddresses(_addresses)
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
|
@ -265,21 +269,27 @@ StatusScrollView {
|
|||
ListModel {
|
||||
id: addresses
|
||||
|
||||
function addAddressesFromString(addresses) {
|
||||
const words = addresses.trim().split(/[\s+,]/)
|
||||
function addAddresses(_addresses) {
|
||||
const existing = new Set()
|
||||
|
||||
for (let i = 0; i < count; i++)
|
||||
existing.add(get(i).address)
|
||||
|
||||
words.forEach(word => {
|
||||
if (word === "" || existing.has(word))
|
||||
_addresses.forEach(address => {
|
||||
if (existing.has(address))
|
||||
return
|
||||
|
||||
const valid = Utils.isValidAddress(word)
|
||||
append({ valid, address: word })
|
||||
const valid = Utils.isValidAddress(address)
|
||||
append({ valid, address })
|
||||
})
|
||||
}
|
||||
|
||||
function addAddressesFromString(addressesString) {
|
||||
const words = addressesString.trim().split(/[\s+,]/)
|
||||
const wordsNonEmpty = words.filter(word => !!word)
|
||||
|
||||
addAddresses(wordsNonEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
function openPopup(popup) {
|
||||
|
|
|
@ -69,6 +69,11 @@ StatusScrollView {
|
|||
int chainId,
|
||||
string accountName)
|
||||
|
||||
signal airdropRequested(string address)
|
||||
signal generalAirdropRequested
|
||||
|
||||
signal remoteDestructRequested(string address)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
|
@ -373,13 +378,19 @@ StatusScrollView {
|
|||
}
|
||||
}
|
||||
|
||||
TokenHoldersPanel {
|
||||
SortableTokenHoldersPanel {
|
||||
visible: !root.preview
|
||||
tokenName: root.name
|
||||
|
||||
model: root.tokenOwnersModel
|
||||
tokenName: root.name
|
||||
showRemotelyDestructMenuItem: !root.isAssetView && root.selfDestruct
|
||||
|
||||
Layout.topMargin: Style.current.padding
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
onAirdropRequested: root.airdropRequested(address)
|
||||
onGeneralAirdropRequested: root.generalAirdropRequested()
|
||||
onRemoteDestructRequested: root.remoteDestructRequested(address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue