feat(AssetsView): business logic not related to ui removed
This commit is contained in:
parent
15452aa79c
commit
436ae9f1f3
|
@ -0,0 +1,271 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import shared.views 1.0
|
||||
import utils 1.0
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import Qt.labs.settings 1.1
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
ListModel {
|
||||
id: assetsModel
|
||||
|
||||
function format(amount, symbol) {
|
||||
return `${amount.toLocaleString(Qt.locale())} ${symbol}`
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
const data = [
|
||||
{
|
||||
key: "key_ETH",
|
||||
symbol: "ETH",
|
||||
name: "Ether",
|
||||
icon: Constants.tokenIcon("ETH", false),
|
||||
balance: 10.0,
|
||||
balanceText: format(10.0, "ETH"),
|
||||
error: "",
|
||||
|
||||
marketDetailsAvailable: true,
|
||||
marketDetailsLoading: true,
|
||||
marketPrice: 0,
|
||||
marketChangePct24hour: 0,
|
||||
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityIcon: Qt.resolvedUrl(""),
|
||||
|
||||
position: 2,
|
||||
canBeHidden: false
|
||||
},
|
||||
{
|
||||
key: "key_SNT",
|
||||
symbol: "SNT",
|
||||
name: "Status",
|
||||
icon: Constants.tokenIcon("SNT", false),
|
||||
balance: 20023.0,
|
||||
balanceText: format(20023.0, "SNT"),
|
||||
error: "",
|
||||
|
||||
marketDetailsAvailable: true,
|
||||
marketDetailsLoading: false,
|
||||
marketPrice: 50.23,
|
||||
marketChangePct24hour: 12,
|
||||
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityIcon: Qt.resolvedUrl(""),
|
||||
|
||||
position: 1,
|
||||
canBeHidden: true
|
||||
},
|
||||
{
|
||||
key: "key_MCT",
|
||||
symbol: "MCT",
|
||||
name: "My custom token",
|
||||
icon: Constants.tokenIcon("ZRX", false),
|
||||
balance: 102.4,
|
||||
balanceText: format(102.4, "MCT"),
|
||||
error: "",
|
||||
|
||||
marketDetailsAvailable: false,
|
||||
marketDetailsLoading: false,
|
||||
marketPrice: 0,
|
||||
marketChangePct24hour: 0,
|
||||
|
||||
communityId: "34",
|
||||
communityName: "Crypto Kitties",
|
||||
communityIcon: Constants.tokenIcon("DAI", false),
|
||||
|
||||
position: 4,
|
||||
canBeHidden: true
|
||||
},
|
||||
{
|
||||
key: "key_DAI",
|
||||
symbol: "DAI",
|
||||
name: "Dai",
|
||||
icon: Constants.tokenIcon("DAI", false),
|
||||
balance: 123.24,
|
||||
balanceText: format(123.24, "DAI"),
|
||||
error: "",
|
||||
|
||||
marketDetailsAvailable: true,
|
||||
marketDetailsLoading: false,
|
||||
marketPrice: 23.23,
|
||||
marketChangePct24hour: 2.3,
|
||||
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityIcon: Qt.resolvedUrl(""),
|
||||
|
||||
position: 3,
|
||||
canBeHidden: true
|
||||
},
|
||||
{
|
||||
key: "key_USDT",
|
||||
symbol: "USDT",
|
||||
name: "USDT",
|
||||
icon: Constants.tokenIcon("USDT", false),
|
||||
balance: 15.24,
|
||||
balanceText: format(15.24, "USDT"),
|
||||
error: "",
|
||||
|
||||
marketDetailsAvailable: true,
|
||||
marketDetailsLoading: false,
|
||||
marketPrice: 0.99,
|
||||
marketChangePct24hour: 0,
|
||||
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
communityIcon: Qt.resolvedUrl(""),
|
||||
|
||||
position: 5,
|
||||
canBeHidden: true
|
||||
},
|
||||
{
|
||||
key: "key_TBT",
|
||||
symbol: "TBT",
|
||||
name: "The best token",
|
||||
icon: Constants.tokenIcon("UNI", false),
|
||||
balance: 102,
|
||||
balanceText: format(102, "TBT"),
|
||||
error: "Pocket Network (POKT) & Infura are currently both "
|
||||
+ "unavailable for %1. %1 balances are as of %2."
|
||||
.arg("TBT").arg("10/06/2024"),
|
||||
|
||||
marketDetailsAvailable: false,
|
||||
marketDetailsLoading: false,
|
||||
marketPrice: 0,
|
||||
marketChangePct24hour: 0,
|
||||
|
||||
communityId: "3423",
|
||||
communityName: "Best tokens",
|
||||
communityIcon: Constants.tokenIcon("UNI", false),
|
||||
|
||||
position: 6,
|
||||
canBeHidden: true
|
||||
}
|
||||
]
|
||||
|
||||
append(data)
|
||||
}
|
||||
}
|
||||
|
||||
SplitView {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
orientation: Qt.Vertical
|
||||
|
||||
Pane {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
AssetsViewNew {
|
||||
anchors.fill: parent
|
||||
|
||||
loading: loadingCheckBox.checked
|
||||
sorterVisible: sorterVisibleCheckBox.checked
|
||||
customOrderAvailable: customOrderAvailableCheckBox.checked
|
||||
|
||||
sendEnabled: sendEnabledCheckBox.checked
|
||||
swapEnabled: swapEnabledCheckBox.checked
|
||||
swapVisible: swapVisibleCheckBox.checked
|
||||
|
||||
balanceError: balanceErrorCheckBox.checked
|
||||
? "Balance error!" : ""
|
||||
|
||||
marketDataError: marketDataErrorCheckBox.checked
|
||||
? "Market data error!" : ""
|
||||
|
||||
model: assetsModel
|
||||
|
||||
onSendRequested: logs.logEvent(`send requested: ${key}`)
|
||||
onReceiveRequested: logs.logEvent(`receive requested: ${key}`)
|
||||
onSwapRequested: logs.logEvent(`swap requested: ${key}`)
|
||||
onAssetClicked: logs.logEvent(`asset clicked: ${key}`)
|
||||
|
||||
onHideRequested: logs.logEvent(`hide requested: ${key}`)
|
||||
onHideCommunityAssets: logs.logEvent(`hide community assets requested: ${communityKey}`)
|
||||
onManageTokensRequested: logs.logEvent(`manage tokens requested`)
|
||||
}
|
||||
}
|
||||
|
||||
Logs {
|
||||
id: logs
|
||||
}
|
||||
|
||||
LogsView {
|
||||
clip: true
|
||||
|
||||
SplitView.preferredHeight: 150
|
||||
SplitView.fillWidth: true
|
||||
|
||||
logText: logs.logText
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
SplitView.preferredWidth: 300
|
||||
|
||||
ColumnLayout {
|
||||
CheckBox {
|
||||
id: loadingCheckBox
|
||||
|
||||
text: "loading"
|
||||
}
|
||||
CheckBox {
|
||||
id: sorterVisibleCheckBox
|
||||
|
||||
text: "sorter visible"
|
||||
}
|
||||
CheckBox {
|
||||
id: customOrderAvailableCheckBox
|
||||
|
||||
text: "custom order available"
|
||||
}
|
||||
CheckBox {
|
||||
id: sendEnabledCheckBox
|
||||
|
||||
text: "send enabled"
|
||||
}
|
||||
CheckBox {
|
||||
id: swapEnabledCheckBox
|
||||
|
||||
text: "swap enabled"
|
||||
}
|
||||
CheckBox {
|
||||
id: swapVisibleCheckBox
|
||||
|
||||
text: "swap visible"
|
||||
}
|
||||
CheckBox {
|
||||
id: balanceErrorCheckBox
|
||||
|
||||
text: "balance error"
|
||||
}
|
||||
CheckBox {
|
||||
id: marketDataErrorCheckBox
|
||||
|
||||
text: "market data error"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Settings {
|
||||
property alias loading: loadingCheckBox.checked
|
||||
property alias filterVisible: sorterVisibleCheckBox.checked
|
||||
property alias customOrderAvailable: customOrderAvailableCheckBox.checked
|
||||
property alias sendEnabled: sendEnabledCheckBox.checked
|
||||
property alias swapEnabled: swapEnabledCheckBox.checked
|
||||
property alias swapVisible: swapVisibleCheckBox.checked
|
||||
property alias balanceError: balanceErrorCheckBox.checked
|
||||
property alias marketDataError: marketDataErrorCheckBox.checked
|
||||
}
|
||||
}
|
||||
|
||||
// category: Views
|
|
@ -0,0 +1,167 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import shared.controls 1.0
|
||||
import utils 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
TokenDelegateNew {
|
||||
anchors.centerIn: parent
|
||||
|
||||
name: nameTextFiled.text
|
||||
balance: balanceTextFiled.text
|
||||
icon: Constants.tokenIcon(iconTextFiled.text, false)
|
||||
|
||||
marketDetailsAvailable: marketDataAvailableCheckBox.checked
|
||||
marketDetailsLoading: marketDataLoadingCheckBox.checked
|
||||
marketCurrencyPrice: marketCurrencyPriceTextFiled.text
|
||||
marketBalance: marketBalanceTextFiled.text
|
||||
marketChangePct24hour: market24ChangeSpinBox.value
|
||||
|
||||
communityId: communityCheckBox.checked ? "42" : ""
|
||||
communityName: communityNameTextField.text
|
||||
communityIcon: Constants.tokenIcon("DAI", false)
|
||||
|
||||
errorTooltipText_1: errorTooltipTextField.text
|
||||
errorTooltipText_2: marketDataErrorTooltipTextField.text
|
||||
|
||||
onCommunityClicked: {
|
||||
console.log("community clicked:", communityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "name:"
|
||||
}
|
||||
TextField {
|
||||
id: nameTextFiled
|
||||
text: "Ether"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "icon:"
|
||||
}
|
||||
TextField {
|
||||
id: iconTextFiled
|
||||
text: "ETH"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "balance:"
|
||||
}
|
||||
TextField {
|
||||
id: balanceTextFiled
|
||||
text: "0,1232 ETH"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
CheckBox {
|
||||
id: marketDataAvailableCheckBox
|
||||
text: "market data available"
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
id: marketDataLoadingCheckBox
|
||||
text: "market data loading"
|
||||
checked: false
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "market balance:"
|
||||
}
|
||||
TextField {
|
||||
id: marketBalanceTextFiled
|
||||
text: "711,23 USD"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "market currency price:"
|
||||
}
|
||||
TextField {
|
||||
id: marketCurrencyPriceTextFiled
|
||||
text: "3 823,23 USD"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "Market data error tooltip:"
|
||||
}
|
||||
TextField {
|
||||
id: marketDataErrorTooltipTextField
|
||||
text: ""
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "market 24 change:"
|
||||
}
|
||||
Slider {
|
||||
id: market24ChangeSpinBox
|
||||
|
||||
value: 0.1
|
||||
|
||||
from: -100
|
||||
to: 200
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
text: "0"
|
||||
|
||||
onClicked: market24ChangeSpinBox.value = 0
|
||||
}
|
||||
}
|
||||
CheckBox {
|
||||
id: communityCheckBox
|
||||
text: "community minted"
|
||||
checked: false
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "community id:"
|
||||
}
|
||||
TextField {
|
||||
id: communityNameTextField
|
||||
text: "Crypto Kitties"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "Error tooltip:"
|
||||
}
|
||||
TextField {
|
||||
id: errorTooltipTextField
|
||||
text: ""
|
||||
}
|
||||
}
|
||||
Label {
|
||||
visible: communityCheckBox.checked
|
||||
&& marketDataAvailableCheckBox.checked
|
||||
text: "Community pill and market details are not expected \n"
|
||||
+ "to occur both for a single token."
|
||||
color: "red"
|
||||
}
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Controls
|
|
@ -35,7 +35,9 @@ ComboBox {
|
|||
currentIndex = d.currentIndex
|
||||
root.createOrEditRequested()
|
||||
} else {
|
||||
if (d.currentIndex === index) // just keep the same sort role and flip the up/down
|
||||
if (index === indexOfValue(SortOrderComboBox.TokenOrderCustom))
|
||||
currentSortOrder = Qt.AscendingOrder
|
||||
else if (d.currentIndex === index) // just keep the same sort role and flip the up/down
|
||||
currentSortOrder = currentSortOrder === Qt.AscendingOrder ? Qt.DescendingOrder : Qt.AscendingOrder
|
||||
|
||||
// update internal index
|
||||
|
@ -211,16 +213,22 @@ ComboBox {
|
|||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: menuDelegate
|
||||
|
||||
required property int index
|
||||
required property var modelData
|
||||
|
||||
readonly property bool isSeparator: text === "---"
|
||||
|
||||
id: menuDelegate
|
||||
width: ListView.view.width
|
||||
highlighted: root.highlightedIndex === index
|
||||
enabled: !isSeparator
|
||||
|
||||
readonly property bool custom:
|
||||
modelData["value"] === SortOrderComboBox.TokenOrderCustom
|
||||
|
||||
visible: {
|
||||
if (modelData["value"] === SortOrderComboBox.TokenOrderCustom) // hide "Custom order" menu entry if none defined
|
||||
if (custom) // hide "Custom order" menu entry if none defined
|
||||
return root.hasCustomOrderDefined
|
||||
return true
|
||||
}
|
||||
|
@ -252,7 +260,7 @@ ComboBox {
|
|||
readonly property int menuIndex: menuDelegate.index
|
||||
readonly property string menuText: menuDelegate.text
|
||||
readonly property string iconName: menuDelegate.icon.name
|
||||
readonly property bool showUpDownArrows: menuDelegate.modelData["sortRoleName"] !== ""
|
||||
readonly property bool showUpDownArrows: !menuDelegate.custom && menuDelegate.modelData["sortRoleName"] !== ""
|
||||
readonly property bool isEditAction: modelData["value"] === SortOrderComboBox.TokenOrderCreateCustom
|
||||
sourceComponent: menuDelegate.isSeparator ? separatorMenuComponent : regularMenuComponent
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
@ -11,9 +11,10 @@ import utils 1.0
|
|||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
signal openInfoPopup()
|
||||
property alias text: sectionTitle.text
|
||||
|
||||
signal infoButtonClicked
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusDialogDivider {
|
||||
|
@ -39,7 +40,7 @@ ColumnLayout {
|
|||
textColor: Theme.palette.baseColor1
|
||||
horizontalPadding: 0
|
||||
verticalPadding: 0
|
||||
onClicked: openInfoPopup()
|
||||
onClicked: root.infoButtonClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import utils 1.0
|
||||
|
||||
TokenDelegateNew {
|
||||
title: Constants.dummyText
|
||||
subTitle: Constants.dummyText
|
||||
asset.name: Constants.dummyText
|
||||
|
||||
statusListItemSubTitle.loading: true
|
||||
statusListItemTitle.loading: true
|
||||
statusListItemIcon.loading: true
|
||||
|
||||
marketDetailsAvailable: true
|
||||
marketDetailsLoading: true
|
||||
|
||||
enabled: false
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import utils 1.0
|
||||
|
||||
StatusListItem {
|
||||
id: root
|
||||
|
||||
property string name
|
||||
property url icon
|
||||
property string balance
|
||||
|
||||
property bool marketDetailsAvailable: false
|
||||
property string marketBalance
|
||||
property bool marketDetailsLoading: false
|
||||
property string marketCurrencyPrice
|
||||
property real marketChangePct24hour
|
||||
|
||||
property string communityId
|
||||
property string communityName
|
||||
property url communityIcon
|
||||
|
||||
property string errorTooltipText_1
|
||||
property string errorTooltipText_2
|
||||
|
||||
signal communityClicked(string communityId)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property bool isCommunityToken: !!root.communityId
|
||||
|
||||
readonly property string textColor: {
|
||||
if (!root.marketDetailsAvailable)
|
||||
return Theme.palette.successColor1
|
||||
|
||||
if (root.marketChangePct24hour === 0)
|
||||
return Theme.palette.baseColor1
|
||||
|
||||
return root.marketChangePct24hour < 0
|
||||
? Theme.palette.dangerColor1
|
||||
: Theme.palette.successColor1
|
||||
}
|
||||
|
||||
readonly property string upDownTriangle: {
|
||||
if (root.marketChangePct24hour === 0)
|
||||
return ""
|
||||
|
||||
return root.marketChangePct24hour < 0 ? "▾" : "▴"
|
||||
}
|
||||
}
|
||||
|
||||
title: root.name
|
||||
subTitle: root.balance
|
||||
asset.name: root.icon
|
||||
asset.isImage: true
|
||||
asset.width: 32
|
||||
asset.height: 32
|
||||
errorIcon.tooltip.maxWidth: 300
|
||||
height: implicitHeight
|
||||
|
||||
statusListItemTitleIcons.sourceComponent: StatusFlatRoundButton {
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
tooltip.text: root.errorTooltipText_1
|
||||
tooltip.maxWidth: 300
|
||||
visible: !!tooltip.text
|
||||
}
|
||||
|
||||
components: [
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
StatusFlatRoundButton {
|
||||
id: errorIcon
|
||||
width: 14
|
||||
height: visible ? 14 : 0
|
||||
icon.width: 14
|
||||
icon.height: 14
|
||||
icon.name: "tiny/warning"
|
||||
icon.color: Theme.palette.dangerColor1
|
||||
tooltip.text: root.errorTooltipText_2
|
||||
tooltip.maxWidth: 200
|
||||
visible: root.marketDetailsAvailable && !!tooltip.text
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
id: currencyBalance
|
||||
|
||||
anchors.right: parent.right
|
||||
visible: !errorIcon.visible && root.marketDetailsAvailable
|
||||
|
||||
loading: root.marketDetailsLoading
|
||||
text: loading ? Constants.dummyText : root.marketBalance
|
||||
}
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
spacing: 6
|
||||
visible: !errorIcon.visible && root.marketDetailsAvailable
|
||||
|
||||
StatusTextWithLoadingState {
|
||||
id: change24HourPercentageText
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
customColor: d.textColor
|
||||
font.pixelSize: 13
|
||||
loading: root.marketDetailsLoading
|
||||
|
||||
text: qsTr("%1 %2%", "[up/down/none character depending on value sign] [localized percentage value]%")
|
||||
.arg(d.upDownTriangle).arg(LocaleUtils.numberToLocaleString(root.marketChangePct24hour, 2))
|
||||
}
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 1
|
||||
height: 12
|
||||
color: Theme.palette.directColor9
|
||||
}
|
||||
StatusTextWithLoadingState {
|
||||
id: currencyPrice
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
customColor: d.textColor
|
||||
font.pixelSize: 13
|
||||
loading: root.marketDetailsLoading
|
||||
text: loading ? Constants.dummyText : root.marketCurrencyPrice
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: d.isCommunityToken
|
||||
|
||||
sourceComponent: ManageTokensCommunityTag {
|
||||
anchors.right: parent.right
|
||||
|
||||
communityImage: root.communityIcon
|
||||
communityName: root.communityName
|
||||
communityId: root.communityId
|
||||
|
||||
asset.letterSize: 12
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onSingleTapped: root.communityClicked(root.communityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
states: State {
|
||||
name: "unknownToken"
|
||||
when: !root.icon.toString()
|
||||
|
||||
PropertyChanges {
|
||||
target: root.asset
|
||||
isLetterIdenticon: true
|
||||
color: Theme.palette.miscColor5
|
||||
name: root.name
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ InformationTag 1.0 InformationTag.qml
|
|||
InformationTile 1.0 InformationTile.qml
|
||||
Input 1.0 Input.qml
|
||||
LoadingTokenDelegate 1.0 LoadingTokenDelegate.qml
|
||||
LoadingTokenDelegateNew 1.0 LoadingTokenDelegateNew.qml
|
||||
LinkPreviewDebugView 1.0 LinkPreviewDebugView.qml
|
||||
ProfilePerspectiveSelector 1.0 ProfilePerspectiveSelector.qml
|
||||
RadioButtonSelector 1.0 RadioButtonSelector.qml
|
||||
|
@ -43,6 +44,7 @@ StyledTextEditWithLoadingState 1.0 StyledTextEditWithLoadingState.qml
|
|||
StyledTextField 1.0 StyledTextField.qml
|
||||
Timer 1.0 Timer.qml
|
||||
TokenDelegate 1.0 TokenDelegate.qml
|
||||
TokenDelegateNew 1.0 TokenDelegateNew.qml
|
||||
TransactionAddress 1.0 TransactionAddress.qml
|
||||
TransactionAddressTile 1.0 TransactionAddressTile.qml
|
||||
TransactionDataTile 1.0 TransactionDataTile.qml
|
||||
|
|
|
@ -246,7 +246,7 @@ Item {
|
|||
width: ListView.view.width
|
||||
required property bool section
|
||||
text: Helpers.assetsSectionTitle(section, holdingItemSelector.hasCommunityTokens, d.isBrowsingGroup, d.isCurrentBrowsingTypeAsset)
|
||||
onOpenInfoPopup: Global.openPopup(communityInfoPopupCmp)
|
||||
onInfoButtonClicked: Global.openPopup(communityInfoPopupCmp)
|
||||
}
|
||||
comboBoxControl.popup.onOpened: comboBoxControl.popup.contentItem.headerItem.focusSearch()
|
||||
comboBoxControl.popup.onClosed: comboBoxControl.popup.contentItem.headerItem.clear()
|
||||
|
|
|
@ -175,7 +175,7 @@ Item {
|
|||
width: parent.width
|
||||
height: !!text ? 52 : 0 // if we bind to some property instead of hardcoded value it wont work nice when switching tabs or going inside collection and back
|
||||
text: Helpers.assetsSectionTitle(section, tokenList.hasCommunityTokens, d.isBrowsingGroup, d.isBrowsingTypeERC20)
|
||||
onOpenInfoPopup: Global.openPopup(communityInfoPopupCmp)
|
||||
onInfoButtonClicked: Global.openPopup(communityInfoPopupCmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
StatusMenu {
|
||||
id: root
|
||||
|
||||
property bool sendEnabled: true
|
||||
property bool swapEnabled: true
|
||||
|
||||
property bool swapVisible: true
|
||||
property bool hideVisible: true
|
||||
property bool communityHideVisible: true
|
||||
|
||||
signal sendRequested
|
||||
signal receiveRequested
|
||||
signal swapRequested
|
||||
signal hideRequested
|
||||
signal communityHideRequested
|
||||
signal manageTokensRequested
|
||||
|
||||
StatusAction {
|
||||
enabled: root.sendEnabled
|
||||
visibleOnDisabled: true
|
||||
icon.name: "send"
|
||||
text: qsTr("Send")
|
||||
onTriggered: root.sendRequested()
|
||||
}
|
||||
StatusAction {
|
||||
icon.name: "receive"
|
||||
text: qsTr("Receive")
|
||||
onTriggered: root.receiveRequested()
|
||||
}
|
||||
StatusAction {
|
||||
icon.name: "swap"
|
||||
text: qsTr("Swap")
|
||||
enabled: root.swapEnabled && root.swapVisible
|
||||
visibleOnDisabled: root.swapVisible
|
||||
onTriggered: root.swapRequested()
|
||||
}
|
||||
StatusMenuSeparator {}
|
||||
StatusAction {
|
||||
icon.name: "settings"
|
||||
text: qsTr("Manage tokens")
|
||||
onTriggered: root.manageTokensRequested()
|
||||
}
|
||||
StatusAction {
|
||||
enabled: root.hideVisible
|
||||
type: StatusAction.Type.Danger
|
||||
icon.name: "hide"
|
||||
text: qsTr("Hide asset")
|
||||
onTriggered: root.hideRequested()
|
||||
}
|
||||
StatusAction {
|
||||
enabled: root.communityHideVisible
|
||||
type: StatusAction.Type.Danger
|
||||
icon.name: "hide"
|
||||
text: qsTr("Hide all assets from this community")
|
||||
onTriggered: root.communityHideRequested()
|
||||
}
|
||||
}
|
|
@ -250,7 +250,7 @@ ColumnLayout {
|
|||
AssetsSectionDelegate {
|
||||
width: parent.width
|
||||
text: qsTr("Community minted")
|
||||
onOpenInfoPopup: Global.openPopup(communityInfoPopupCmp)
|
||||
onInfoButtonClicked: Global.openPopup(communityInfoPopupCmp)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import QtQml.Models 2.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
import shared.controls 1.0
|
||||
import shared.popups 1.0
|
||||
import utils 1.0
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
|
||||
Control {
|
||||
id: root
|
||||
|
||||
/**
|
||||
Expected model structure:
|
||||
|
||||
key [string] - unique identifier of a token, e.g "0x3234235"
|
||||
symbol [string] - token's symbol e.g. "ETH" or "SNT"
|
||||
name [string] - token's name e.g. "Ether" or "Dai"
|
||||
icon [url] - token's icon url
|
||||
balance [double] - tokens balance is the commonly used unit, e.g. 1.2 for 1.2 ETH, used
|
||||
for sorting and computing market value
|
||||
balanceText [string] - formatted and localized balance. This is not done internally because
|
||||
it may depend on many external factors
|
||||
error [string] - error message related to balance
|
||||
|
||||
marketDetailsAvailable [bool] - specifies if market datails are available for given token
|
||||
marketDetailsLoading [bool] - specifies if market datails are available for given token
|
||||
marketPrice [double] - specifies market price in currently used currency
|
||||
marketChangePct24hour [double] - percentage price change in last 24 hours, e.g. 0.5 for 0.5% of price change
|
||||
|
||||
communityId [string] - for community assets, unique identifier of a community, e.g. "0x6734235"
|
||||
communityName [string] - for community assets, name of a community e.g. "Crypto Kitties"
|
||||
communityIcon [url] - for community assets, community's icon url
|
||||
|
||||
position [int] - if custom order available, display position defined by the user via token management
|
||||
canBeHidden [bool] - specifies if given token can be hidden (e.g. ETH should be always visible)
|
||||
**/
|
||||
property var model
|
||||
|
||||
// enables global loading state useful when real data are not yet available
|
||||
property bool loading
|
||||
|
||||
// shows/hides list sorter
|
||||
property bool sorterVisible
|
||||
|
||||
// allows/disables choosing custom sort order from a sorter
|
||||
property bool customOrderAvailable
|
||||
|
||||
// switches configuring right click menu
|
||||
property bool sendEnabled: true
|
||||
property bool swapEnabled: true
|
||||
property bool swapVisible: true
|
||||
|
||||
property string balanceError
|
||||
|
||||
// global market data error, presented for all tokens expecting market data
|
||||
property string marketDataError
|
||||
|
||||
// formatting function for fiat currency values
|
||||
property var formatFiat: balance => `${balance.toLocaleString(Qt.locale())} XYZ`
|
||||
|
||||
signal sendRequested(string key)
|
||||
signal receiveRequested(string key)
|
||||
signal swapRequested(string key)
|
||||
signal assetClicked(string key)
|
||||
signal communityClicked(string communityKey)
|
||||
signal hideRequested(string key)
|
||||
signal hideCommunityAssets(string communityKey)
|
||||
signal manageTokensRequested
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property int loadingItemsCount: 25
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: sfpm
|
||||
|
||||
sourceModel: root.model
|
||||
|
||||
proxyRoles: [
|
||||
// helper role for rendering section delegate
|
||||
FastExpressionRole {
|
||||
name: "isCommunity"
|
||||
expression: !!communityId ? "community" : ""
|
||||
expectedRoles: ["communityId"]
|
||||
},
|
||||
FastExpressionRole {
|
||||
name: "marketBalance"
|
||||
expression: balance * marketPrice
|
||||
expectedRoles: ["balance", "marketPrice"]
|
||||
},
|
||||
FastExpressionRole {
|
||||
name: "change1DayFiat"
|
||||
expression: marketBalance * (1 - (1 / (marketChangePct24hour / 100 + 1)))
|
||||
expectedRoles: ["marketBalance", "marketChangePct24hour"]
|
||||
}
|
||||
]
|
||||
|
||||
sorters: [
|
||||
RoleSorter {
|
||||
roleName: "isCommunity"
|
||||
},
|
||||
RoleSorter {
|
||||
roleName: sortOrderComboBox.currentSortRoleName
|
||||
sortOrder: sortOrderComboBox.currentSortOrder
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: false
|
||||
Layout.preferredHeight: root.sorterVisible ? implicitHeight : 0
|
||||
|
||||
opacity: root.sorterVisible ? 1 : 0
|
||||
spacing: 20
|
||||
visible: opacity > 0
|
||||
|
||||
Behavior on Layout.preferredHeight {
|
||||
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
|
||||
}
|
||||
|
||||
StatusDialogDivider { Layout.fillWidth: true }
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
|
||||
spacing: Style.current.halfPadding
|
||||
|
||||
StatusBaseText {
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: Style.current.additionalTextSize
|
||||
text: qsTr("Sort by:")
|
||||
}
|
||||
|
||||
SortOrderComboBox {
|
||||
id: sortOrderComboBox
|
||||
|
||||
objectName: "cmbTokenOrder"
|
||||
hasCustomOrderDefined: root.customOrderAvailable
|
||||
|
||||
model: [
|
||||
{ value: SortOrderComboBox.TokenOrderCurrencyBalance,
|
||||
text: qsTr("Asset balance value"), icon: "", sortRoleName: "marketBalance" },
|
||||
{ value: SortOrderComboBox.TokenOrderBalance,
|
||||
text: qsTr("Asset balance"), icon: "", sortRoleName: "balance" },
|
||||
{ value: SortOrderComboBox.TokenOrderCurrencyPrice,
|
||||
text: qsTr("Asset value"), icon: "", sortRoleName: "marketPrice" },
|
||||
{ value: SortOrderComboBox.TokenOrder1DChange,
|
||||
text: qsTr("1d change: balance value"), icon: "", sortRoleName: "change1DayFiat" },
|
||||
{ value: SortOrderComboBox.TokenOrderAlpha,
|
||||
text: qsTr("Asset name"), icon: "", sortRoleName: "name" },
|
||||
{ value: SortOrderComboBox.TokenOrderCustom,
|
||||
text: qsTr("Custom order"), icon: "", sortRoleName: "position" },
|
||||
{ value: SortOrderComboBox.TokenOrderNone,
|
||||
text: "---", icon: "", sortRoleName: "" }, // separator
|
||||
{ value: SortOrderComboBox.TokenOrderCreateCustom,
|
||||
text: hasCustomOrderDefined ? qsTr("Edit custom order →") : qsTr("Create custom order →"),
|
||||
icon: "", sortRoleName: "" }
|
||||
]
|
||||
onCreateOrEditRequested: {
|
||||
root.manageTokensRequested()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusDialogDivider { Layout.fillWidth: true }
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: regularModel
|
||||
|
||||
model: sfpm
|
||||
|
||||
delegate: TokenDelegateNew {
|
||||
objectName: `AssetView_TokenListItem_${model.symbol}`
|
||||
|
||||
width: ListView.view.width
|
||||
|
||||
name: model.name
|
||||
icon: model.icon
|
||||
balance: model.balanceText
|
||||
marketBalance: root.formatFiat(model.marketBalance)
|
||||
|
||||
marketDetailsAvailable: model.marketDetailsAvailable
|
||||
marketDetailsLoading: model.marketDetailsLoading
|
||||
marketCurrencyPrice: root.formatFiat(model.change1DayFiat)
|
||||
marketChangePct24hour: model.marketChangePct24hour
|
||||
|
||||
communityId: model.communityId
|
||||
communityName: model.communityName ?? ""
|
||||
communityIcon: model.communityIcon ?? ""
|
||||
|
||||
errorTooltipText_1: model.error
|
||||
errorTooltipText_2: root.marketDataError
|
||||
|
||||
errorMode: !!root.balanceError
|
||||
errorIcon.tooltip.text: root.balanceError
|
||||
|
||||
onClicked: {
|
||||
if (mouse.button === Qt.LeftButton)
|
||||
root.assetClicked(model.key)
|
||||
else if (mouse.button === Qt.RightButton)
|
||||
tokenContextMenu.createObject(this, { model }).popup(mouse)
|
||||
}
|
||||
|
||||
onCommunityClicked: root.communityClicked(model.communityId)
|
||||
}
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: loadingModel
|
||||
|
||||
model: d.loadingItemsCount
|
||||
|
||||
delegate: LoadingTokenDelegateNew {
|
||||
objectName: `AssetView_LoadingTokenDelegate_${model.index}`
|
||||
|
||||
width: ListView.view.width
|
||||
}
|
||||
}
|
||||
|
||||
StatusListView {
|
||||
id: listView
|
||||
|
||||
objectName: "assetViewStatusListView"
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
model: root.loading ? loadingModel : regularModel
|
||||
|
||||
section {
|
||||
property: "isCommunity"
|
||||
delegate: AssetsSectionDelegate {
|
||||
width: parent.width
|
||||
text: qsTr("Community minted")
|
||||
onInfoButtonClicked: communityInfoPopup.createObject(this).open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: tokenContextMenu
|
||||
|
||||
AssetContextMenu {
|
||||
required property var model
|
||||
|
||||
readonly property string key: model.key
|
||||
readonly property string communityKey: model.communityId
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
sendEnabled: root.sendEnabled
|
||||
swapEnabled: root.swapEnabled
|
||||
swapVisible: root.swapVisible
|
||||
hideVisible: model.canBeHidden
|
||||
communityHideVisible: !!model.isCommunity
|
||||
|
||||
onSendRequested: root.sendRequested(key)
|
||||
onReceiveRequested: root.receiveRequested(key)
|
||||
onSwapRequested: root.swapRequested(key)
|
||||
|
||||
onHideRequested:
|
||||
confirmHideAssetPopup.createObject(parent, { model }).open()
|
||||
onCommunityHideRequested:
|
||||
confirmHideCommunityAssetsPopup.createObject(parent, { model }).open()
|
||||
|
||||
onManageTokensRequested: root.manageTokensRequested()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: communityInfoPopup
|
||||
|
||||
CommunityAssetsInfoPopup {
|
||||
destroyOnClose: true
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: confirmHideAssetPopup
|
||||
|
||||
ConfirmHideAssetPopup {
|
||||
destroyOnClose: true
|
||||
|
||||
required property var model
|
||||
|
||||
symbol: model.symbol
|
||||
name: model.name
|
||||
icon: model.icon
|
||||
|
||||
onConfirmButtonClicked: {
|
||||
root.hideRequested(model.key)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: confirmHideCommunityAssetsPopup
|
||||
|
||||
ConfirmHideCommunityAssetsPopup {
|
||||
required property var model
|
||||
|
||||
name: model.communityName
|
||||
icon: model.communityIcon
|
||||
|
||||
onConfirmButtonClicked: {
|
||||
root.hideCommunityAssets(model.communityId)
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import shared.popups 1.0
|
||||
|
||||
ConfirmationDialog {
|
||||
required property string symbol
|
||||
required property string name
|
||||
required property string icon
|
||||
|
||||
width: 520
|
||||
|
||||
confirmButtonLabel: qsTr("Hide asset")
|
||||
cancelBtnType: ""
|
||||
showCancelButton: true
|
||||
headerSettings.title: qsTr("Hide %1 (%2)").arg(name).arg(symbol)
|
||||
headerSettings.asset.name: icon
|
||||
confirmationText: qsTr("Are you sure you want to hide %1 (%2)? You will no longer see or be able to interact with this asset anywhere inside Status.")
|
||||
.arg(name).arg(symbol)
|
||||
|
||||
onCancelButtonClicked: close()
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import shared.popups 1.0
|
||||
|
||||
ConfirmationDialog {
|
||||
required property string name
|
||||
required property string icon
|
||||
|
||||
width: 520
|
||||
|
||||
confirmButtonLabel: qsTr("Hide '%1' assets").arg(name)
|
||||
cancelBtnType: ""
|
||||
showCancelButton: true
|
||||
headerSettings.title: qsTr("Hide %1 community assets").arg(name)
|
||||
headerSettings.asset.name: icon
|
||||
confirmationText: qsTr("Are you sure you want to hide all community assets minted by %1? You will no longer see or be able to interact with these assets anywhere inside Status.").arg(name)
|
||||
|
||||
onCancelButtonClicked: close()
|
||||
}
|
|
@ -1,16 +1,20 @@
|
|||
AssetContextMenu 1.0 AssetContextMenu.qml
|
||||
AssetsView 1.0 AssetsView.qml
|
||||
AssetsViewNew 1.0 AssetsViewNew.qml
|
||||
ConfirmHideAssetPopup 1.0 ConfirmHideAssetPopup.qml
|
||||
ConfirmHideCommunityAssetsPopup 1.0 ConfirmHideCommunityAssetsPopup.qml
|
||||
EnsResolver 1.0 EnsResolver.qml
|
||||
ExistingContacts 1.0 ExistingContacts.qml
|
||||
HistoryView 1.0 HistoryView.qml
|
||||
NoFriendsRectangle 1.0 NoFriendsRectangle.qml
|
||||
PasswordView 1.0 PasswordView.qml
|
||||
PasswordConfirmationView 1.0 PasswordConfirmationView.qml
|
||||
PasswordView 1.0 PasswordView.qml
|
||||
PickedContacts 1.0 PickedContacts.qml
|
||||
ProfileDialogView 1.0 ProfileDialogView.qml
|
||||
SearchResults 1.0 SearchResults.qml
|
||||
TransactionSigner 1.0 TransactionSigner.qml
|
||||
SyncingCodeInstructions 1.0 SyncingCodeInstructions.qml
|
||||
SyncingDeviceView 1.0 SyncingDeviceView.qml
|
||||
SyncingDisplayCode 1.0 SyncingDisplayCode.qml
|
||||
SyncingErrorMessage 1.0 SyncingErrorMessage.qml
|
||||
SyncingCodeInstructions 1.0 SyncingCodeInstructions.qml
|
||||
SyncingEnterCode 1.0 SyncingEnterCode.qml
|
||||
SyncingErrorMessage 1.0 SyncingErrorMessage.qml
|
||||
TransactionSigner 1.0 TransactionSigner.qml
|
||||
|
|
Loading…
Reference in New Issue