status-desktop/ui/app/AppLayouts/Chat/views/communities/CommunityTokenView.qml

397 lines
14 KiB
QML
Raw Normal View History

import QtQuick 2.15
import QtQuick.Layouts 1.14
import QtGraphicalEffects 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import utils 1.0
import shared.panels 1.0
import AppLayouts.Chat.panels.communities 1.0
StatusScrollView {
id: root
property int viewWidth: 560 // by design
property bool preview: false
property bool isAssetView: false
// Token properties
property alias artworkSource: image.source
property rect artworkCropRect
property string name
property alias symbol: symbolBox.value
property alias description: descriptionItem.text
property int supplyAmount
property int remainingTokens
property bool infiniteSupply
property alias accountName: accountBox.value
property int chainId
property string chainIcon
property alias chainName: chainText.text
property var tokenOwnersModel
property int deployState: Constants.ContractTransactionStatus.None
property int burnState: Constants.ContractTransactionStatus.None
// Collectible object properties (ERC721)
property bool transferable
property bool selfDestruct
property int remotelyDestructState: Constants.ContractTransactionStatus.None
// Asset properties (ERC20)
property alias assetDecimals: decimalsBox.value
signal mintCollectible(url artworkSource,
string name,
string symbol,
string description,
int supply,
bool infiniteSupply,
bool transferable,
bool selfDestruct,
int chainId,
string accountName)
signal mintAsset(url artworkSource,
string name,
string symbol,
string description,
int supply,
bool infiniteSupply,
int decimals,
int chainId,
string accountName)
signal airdropRequested(string address)
signal generalAirdropRequested
signal remoteDestructRequested(string address)
QtObject {
id: d
readonly property int imageSelectorRectSize: root.isAssetView ? 104 : 280
readonly property int iconSize: 20
readonly property string infiniteSymbol: "∞"
function startAnimation(isBurn) {
totalbox.highlighted = true
if(isBurn)
remainingBox.highlighted = true
}
}
padding: 0
onRemotelyDestructStateChanged: if(remotelyDestructState === Constants.ContractTransactionStatus.Completed) d.startAnimation(false)
onBurnStateChanged: if(burnState === Constants.ContractTransactionStatus.Completed) d.startAnimation(true)
ColumnLayout {
id: mainLayout
width: root.viewWidth
spacing: Style.current.padding
RowLayout {
visible: !root.preview && ((root.deployState === Constants.ContractTransactionStatus.InProgress) ||
(root.deployState === Constants.ContractTransactionStatus.Failed))
spacing: Style.current.halfPadding
StatusDotsLoadingIndicator {
visible: (root.deployState === Constants.ContractTransactionStatus.InProgress)
}
StatusIcon {
visible: (root.deployState === Constants.ContractTransactionStatus.Failed)
icon: "warning"
color: Theme.palette.dangerColor1
}
StatusBaseText {
elide: Text.ElideRight
font.pixelSize: Theme.primaryTextFontSize
text: (root.deployState === Constants.ContractTransactionStatus.InProgress) ?
(root.isAssetView ?
qsTr("Asset is being minted") : qsTr("Collectible is being minted")) :
(root.deployState === Constants.ContractTransactionStatus.Failed) ?
(root.isAssetView ? qsTr("Asset minting failed") : qsTr("Collectible minting failed")) : ""
color: (root.deployState === Constants.ContractTransactionStatus.Failed) ? Theme.palette.dangerColor1 : Theme.palette.directColor1
}
}
Rectangle {
Layout.preferredHeight: d.imageSelectorRectSize
Layout.preferredWidth: Layout.preferredHeight
radius: root.isAssetView ? Layout.preferredWidth / 2 : 8
color:Theme.palette.baseColor2
clip: true
Image {
id: image
anchors.fill: parent
fillMode: Image.PreserveAspectFit
visible: false
sourceClipRect: root.artworkCropRect ? root.artworkCropRect : undefined
}
OpacityMask {
anchors.fill: image
source: image
maskSource: parent
}
}
Flow {
spacing: Style.current.halfPadding
Layout.fillWidth: true
component CustomPreviewBox: Rectangle {
id: previewBox
property string label
property string value
property bool isLoading: false
property bool highlighted: false
radius: 8
border.color: Theme.palette.baseColor2
implicitWidth: Math.min(boxContent.implicitWidth + Style.current.padding, mainLayout.width)
implicitHeight: boxContent.implicitHeight + Style.current.padding
states: [
State {
when: !previewBox.highlighted
PropertyChanges { target: previewBox; color: "transparent" }
},
State {
when: previewBox.highlighted
PropertyChanges { target: previewBox; color: Theme.palette.primaryColor3 }
}
]
onHighlightedChanged: if(highlighted) animation.start()
ColumnLayout {
id: boxContent
anchors.centerIn: parent
spacing: 2
StatusBaseText {
Layout.fillWidth: true
text: previewBox.label
elide: Text.ElideRight
font.pixelSize: 13
color: Theme.palette.baseColor1
}
RowLayout {
spacing: 3
StatusBaseText {
text: StatusQUtils.Emoji.fromCodePoint("1f525") // :fire: emoji
font.pixelSize: Theme.tertiaryTextFontSize
visible: previewBox.isLoading
color: Theme.palette.directColor1
}
StatusBaseText {
Layout.maximumWidth: mainLayout.width - Style.current.padding
text: previewBox.value
elide: Text.ElideRight
font.pixelSize: Theme.primaryTextFontSize
color: Theme.palette.directColor1
}
StatusLoadingIndicator {
Layout.preferredHeight: Theme.primaryTextFontSize
Layout.preferredWidth: Layout.preferredHeight
Layout.leftMargin: 6
Layout.rightMargin: 3
visible: previewBox.isLoading
color: Theme.palette.primaryColor1
}
}
}
Timer {
id: animation
interval: 1500
onRunningChanged: if(!running) previewBox.highlighted = false
}
}
CustomPreviewBox {
id: symbolBox
label: qsTr("Symbol")
}
CustomPreviewBox {
id: totalbox
label: qsTr("Total")
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(root.supplyAmount)
isLoading: !root.infiniteSupply &&
((root.remotelyDestructState === Constants.ContractTransactionStatus.InProgress) ||
(root.burnState === Constants.ContractTransactionStatus.InProgress))
}
CustomPreviewBox {
id: remainingBox
label: qsTr("Remaining")
value: root.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(root.remainingTokens)
isLoading: !root.infiniteSupply && (root.burnState === Constants.ContractTransactionStatus.InProgress)
}
CustomPreviewBox {
id: decimalsBox
visible: root.isAssetView
label: qsTr("DP")
}
CustomPreviewBox {
visible: !root.isAssetView
label: qsTr("Transferable")
value: root.transferable ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: !root.isAssetView
label: qsTr("Remotely destructible")
value: root.selfDestruct ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
id: accountBox
label: qsTr("Account")
}
Rectangle {
height: symbolBox.height
width: rowChain.implicitWidth + 2 * Style.current.padding
border.width: 1
radius: 8
border.color: Theme.palette.baseColor2
color: "transparent"
RowLayout {
id: rowChain
anchors.centerIn: parent
spacing: Style.current.padding
SVGImage {
id: chainIcon
Layout.alignment: Qt.AlignVCenter
height: 24
width: height
source: Style.svg(root.chainIcon)
}
StatusBaseText {
id: chainText
Layout.alignment: Qt.AlignVCenter
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
}
}
}
}
StatusBaseText {
id: descriptionItem
Layout.fillWidth: true
wrapMode: TextEdit.WordWrap
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
}
RowLayout {
visible: root.preview
Layout.fillWidth: true
StatusIcon {
Layout.preferredWidth: d.iconSize
Layout.preferredHeight: d.iconSize
Layout.alignment: Qt.AlignTop
color: Theme.palette.baseColor1
icon: "info"
}
StatusBaseText {
Layout.fillWidth: true
wrapMode: Text.Wrap
font.pixelSize: Style.current.primaryTextFontSize
color: Theme.palette.baseColor1
text: qsTr("Make sure youre happy with your token before minting it as it cant be edited later")
}
}
StatusButton {
visible: root.preview
Layout.preferredHeight: 44
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.topMargin: Style.current.halfPadding
text: qsTr("Mint")
onClicked: {
if(root.isAssetView) {
root.mintAsset(root.artworkSource,
root.name,
root.symbol,
root.description,
root.supplyAmount,
root.infiniteSupply,
root.assetDecimals,
root.chainId,
root.accountName)
} else {
root.mintCollectible(root.artworkSource,
root.name,
root.symbol,
root.description,
root.supplyAmount,
root.infiniteSupply,
root.transferable,
root.selfDestruct,
root.chainId,
root.accountName)
}
}
}
SortableTokenHoldersPanel {
visible: !root.preview
model: root.tokenOwnersModel
tokenName: root.name
showRemotelyDestructMenuItem: !root.isAssetView && root.selfDestruct
Layout.topMargin: Style.current.padding
Layout.fillWidth: true
onAirdropRequested: root.airdropRequested(address)
onGeneralAirdropRequested: root.generalAirdropRequested()
onRemoteDestructRequested: root.remoteDestructRequested(address)
}
}
}