status-desktop/ui/app/AppLayouts/Communities/panels/TokenInfoPanel.qml

275 lines
9.0 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
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 AppLayouts.Communities.helpers 1.0
import utils 1.0
import shared.panels 1.0
Control {
id: root
// Panel properties:
property bool preview: false
property bool accountBoxVisible: true
property bool networkBoxVisible: true
// Token object properties:
/* required */ property TokenObject token // https://bugreports.qt.io/browse/QTBUG-84269
readonly property bool isAssetPanel: token.type === Constants.TokenType.ERC20
QtObject {
id: d
readonly property int imageSelectorRectSize: root.isAssetPanel ? 104 : 280
readonly property string infiniteSymbol: "∞"
readonly property int burnState: token.burnState
function startAnimation(isBurn) {
totalbox.highlighted = true
if(isBurn)
remainingBox.highlighted = true
}
onBurnStateChanged: if(burnState === Constants.ContractTransactionStatus.Completed) d.startAnimation(true)
}
implicitWidth: 560 // by design
contentItem: ColumnLayout {
id: mainLayout
spacing: Style.current.padding
// General artwork representation:
Rectangle {
visible: !token.isPrivilegedToken
Layout.preferredHeight: d.imageSelectorRectSize
Layout.preferredWidth: Layout.preferredHeight
radius: root.isAssetPanel ? Layout.preferredWidth / 2 : 8
color:Theme.palette.baseColor2
Image {
id: image
readonly property rect imageCropRect: token.artworkCropRect
anchors.fill: parent
fillMode: Image.PreserveAspectFit
visible: false
source: token.artworkSource
sourceClipRect: imageCropRect ? imageCropRect : undefined
}
OpacityMask {
anchors.fill: image
source: image
maskSource: parent
}
}
// Special artwork representation for `Owner and Master Token` tokens:
PrivilegedTokenArtworkPanel {
visible: token.isPrivilegedToken
size: PrivilegedTokenArtworkPanel.Size.Large
artwork: token.artworkSource
color: token.color
isOwner: token.privilegesLevel === Constants.TokenPrivilegesLevel.Owner
}
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: Style.current.additionalTextSize
color: Theme.palette.baseColor1
}
RowLayout {
spacing: 3
StatusBaseText {
text: StatusQUtils.Emoji.fromCodePoint("1f525") // :fire: emoji
font.pixelSize: Style.current.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")
value: token.symbol
}
CustomPreviewBox {
id: totalbox
label: qsTr("Total")
value: token.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(token.supply)
isLoading: !token.infiniteSupply &&
((!root.isAssetPanel && token.remotelyDestructState === Constants.ContractTransactionStatus.InProgress) ||
(d.burnState === Constants.ContractTransactionStatus.InProgress))
}
CustomPreviewBox {
id: remainingBox
readonly property int remainingTokens: root.preview ? token.supply : token.remainingTokens
label: qsTr("Remaining")
value: token.infiniteSupply ? d.infiniteSymbol : LocaleUtils.numberToLocaleString(remainingTokens)
isLoading: !token.infiniteSupply && (d.burnState === Constants.ContractTransactionStatus.InProgress)
}
CustomPreviewBox {
visible: root.isAssetPanel
label: qsTr("DP")
value: token.decimals
}
CustomPreviewBox {
visible: !root.isAssetPanel
label: qsTr("Transferable")
value: token.transferable ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: !root.isAssetPanel
label: qsTr("Destructible")
value: token.remotelyDestruct ? qsTr("Yes") : qsTr("No")
}
CustomPreviewBox {
visible: root.accountBoxVisible
label: qsTr("Account")
value: token.accountName
}
Rectangle {
visible: root.networkBoxVisible
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 {
Layout.alignment: Qt.AlignVCenter
height: 24
width: height
source: token.chainIcon ? Style.svg(token.chainIcon) : undefined
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
text: token.chainName
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
}
}
}
}
StatusBaseText {
Layout.fillWidth: true
text: token.description
wrapMode: TextEdit.WordWrap
font.pixelSize: Theme.primaryTextFontSize
lineHeight: 1.2
}
}
Connections {
target: token
function onRemotelyDestructStateChanged() {
if(token.remotelyDestructState === Constants.ContractTransactionStatus.Completed) d.startAnimation(false)
}
}
}