feat(WalletSettings): Display token list as well as popup to see each token in it
- It creates new component `SupportedTokensListsPanel`. - It updates tokens list tab content with the expected one. - It creates new component `TokenListPopup`. - It adds support to new created components in `storybook`. Closes #12374
This commit is contained in:
parent
b1064644e8
commit
e0179bb2b5
|
@ -0,0 +1,71 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import Storybook 1.0
|
||||
import Models 1.0
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import AppLayouts.Profile.panels 1.0
|
||||
import AppLayouts.Profile.stores 1.0
|
||||
|
||||
import StatusQ 0.1
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
readonly property var sourcesOfTokensModel: SourceOfTokensModel {}
|
||||
readonly property var flatTokensModel: FlatTokensModel {}
|
||||
readonly property var joinModel: LeftJoinModel {
|
||||
leftModel: root.flatTokensModel
|
||||
rightModel: NetworksModel.allNetworks
|
||||
|
||||
joinRole: "chainId"
|
||||
}
|
||||
readonly property var tokensProxyModel: SortFilterProxyModel {
|
||||
sourceModel: joinModel
|
||||
|
||||
proxyRoles: [
|
||||
ExpressionRole {
|
||||
name: "explorerUrl"
|
||||
expression: { return "https://status.im/" }
|
||||
},
|
||||
ExpressionRole {
|
||||
name: "jsArraySources"
|
||||
expression: model.sources.split(";")
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
orientation: Qt.Vertical
|
||||
|
||||
Logs { id: logs }
|
||||
|
||||
|
||||
Pane {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
SupportedTokenListsPanel {
|
||||
anchors.fill: parent
|
||||
sourcesOfTokensModel: root.sourcesOfTokensModel
|
||||
tokensListModel: root.tokensProxyModel
|
||||
|
||||
onItemClicked: logs.logEvent("SupportedTokenListsPanel::onItemClicked --> Key --> " + key)
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumHeight: 100
|
||||
SplitView.preferredHeight: 200
|
||||
|
||||
logsView.logText: logs.logText
|
||||
}
|
||||
}
|
||||
|
||||
// category: Panels
|
||||
// https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?type=design&node-id=18057%3A239410&mode=design&t=zSZ650alzNvE28GO-1
|
|
@ -0,0 +1,148 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import Storybook 1.0
|
||||
import Models 1.0
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import StatusQ 0.1
|
||||
|
||||
import AppLayouts.Profile.popups 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
Logs { id: logs }
|
||||
|
||||
readonly property var sourcesOfTokensModel: SourceOfTokensModel {}
|
||||
readonly property var flatTokensModel: FlatTokensModel {}
|
||||
readonly property var joinModel: LeftJoinModel {
|
||||
leftModel: root.flatTokensModel
|
||||
rightModel: NetworksModel.allNetworks
|
||||
|
||||
joinRole: "chainId"
|
||||
}
|
||||
readonly property var tokensProxyModel: SortFilterProxyModel {
|
||||
sourceModel: joinModel
|
||||
|
||||
proxyRoles: [
|
||||
ExpressionRole {
|
||||
name: "explorerUrl"
|
||||
expression: { return "https://status.im/" }
|
||||
},
|
||||
ExpressionRole {
|
||||
name: "jsArraySources"
|
||||
expression: model.sources.split(";")
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
SplitView {
|
||||
orientation: Qt.Vertical
|
||||
SplitView.fillWidth: true
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
PopupBackground {
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: sourcesOfTokensModel
|
||||
|
||||
filters: ValueFilter {
|
||||
id: keyFilter
|
||||
|
||||
roleName: "key"
|
||||
value : uniswapBtn.checked ? "uniswap" : "status"
|
||||
}
|
||||
}
|
||||
|
||||
delegate: QtObject {
|
||||
id: delegate
|
||||
|
||||
required property string name
|
||||
required property string image
|
||||
required property string source
|
||||
required property int updatedAt
|
||||
required property string version
|
||||
required property int tokensCount
|
||||
|
||||
readonly property TokenListPopup popup: TokenListPopup {
|
||||
parent: root
|
||||
|
||||
visible: true
|
||||
modal: false
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
sourceName: delegate.name
|
||||
sourceImage: delegate.image
|
||||
sourceUrl: delegate.source
|
||||
sourceUpdatedAt: delegate.updatedAt
|
||||
sourceVersion: delegate.version
|
||||
tokensCount: delegate.tokensCount
|
||||
|
||||
tokensListModel: SortFilterProxyModel {
|
||||
sourceModel: root.tokensProxyModel
|
||||
|
||||
// Filter by source
|
||||
filters: ExpressionFilter {
|
||||
expression: model.jsArraySources.includes(keyFilter.value)
|
||||
}
|
||||
}
|
||||
|
||||
onLinkClicked: logs.logEvent("TokenListPopup::onLinkClicked --> " + link)
|
||||
onClosed: keyFilter.value = ""
|
||||
Component.onCompleted: open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumHeight: 100
|
||||
SplitView.preferredHeight: 150
|
||||
|
||||
logsView.logText: logs.logText
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
SplitView.minimumWidth: 300
|
||||
SplitView.preferredWidth: 300
|
||||
|
||||
Column {
|
||||
spacing: 12
|
||||
|
||||
Label {
|
||||
text: "Token List:"
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: uniswapBtn
|
||||
|
||||
text: "Uniswap"
|
||||
checked: true
|
||||
|
||||
onCheckedChanged: keyFilter.value = "uniswap"
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: statusBtn
|
||||
|
||||
text: "Status"
|
||||
|
||||
onCheckedChanged: keyFilter.value = "status"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Popups
|
||||
// https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?type=design&node-id=18057%3A239798&mode=design&t=Vnm5GS8EZFLpeRAY-1
|
|
@ -0,0 +1,141 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import Models 1.0
|
||||
|
||||
ListModel {
|
||||
readonly property string uniswap: "uniswap" //SourceOfTokensModel.uniswap
|
||||
readonly property string status: "status" //SourceOfTokensModel.status
|
||||
readonly property string custom: "custom" //SourceOfTokensModel.custom
|
||||
|
||||
|
||||
readonly property var data: [
|
||||
{
|
||||
key: "0",
|
||||
name: "Unisocks",
|
||||
symbol: "SOCKS",
|
||||
sources: uniswap + ";" + status,
|
||||
chainId: NetworksModel.ethNet,
|
||||
address: "0x0000000000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.socks,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "1",
|
||||
name: "Unisocks",
|
||||
symbol: "SOCKS",
|
||||
sources: uniswap + ";" + status,
|
||||
chainId: NetworksModel.optimismNet,
|
||||
address: "0x00000000000000000000000000000000000ade21",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.socks,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
name: "Ox",
|
||||
symbol: "ZRX",
|
||||
sources: uniswap + ";" + status,
|
||||
chainId: NetworksModel.ethNet,
|
||||
address: "0x1230000000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.zrx,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
name: "1inch",
|
||||
symbol: "1INCH",
|
||||
sources: uniswap + ";" + status,
|
||||
chainId: NetworksModel.ethNet,
|
||||
address: "0x4321000000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.inch,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "4",
|
||||
name: "Aave",
|
||||
symbol: "AAVE",
|
||||
sources: uniswap + ";" + status,
|
||||
chainId: NetworksModel.arbitrumNet,
|
||||
address: "0x6543000000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.aave,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "5",
|
||||
name: "Amp",
|
||||
symbol: "AMP",
|
||||
sources: uniswap,
|
||||
chainId: NetworksModel.arbitrumNet,
|
||||
address: "0x6543700000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.amp,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "6",
|
||||
name: "Dai",
|
||||
symbol: "DAI",
|
||||
sources: uniswap,
|
||||
chainId: NetworksModel.optimismNet,
|
||||
address: "0xabc2000000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.dai,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "7",
|
||||
name: "snt",
|
||||
symbol: "SNT",
|
||||
sources: status,
|
||||
chainId: NetworksModel.optimismNet,
|
||||
address: "0xbbc2000000000000000000000000000000000123",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.snt,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
},
|
||||
{
|
||||
key: "8",
|
||||
name: "snt",
|
||||
symbol: "SNT",
|
||||
sources: status,
|
||||
chainId: NetworksModel.ethNet,
|
||||
address: "0xbbc200000000000000000000000000000000abcd",
|
||||
decimals: "18",
|
||||
image: ModelsData.assets.snt,
|
||||
type: 1,
|
||||
communityId: "",
|
||||
description: "",
|
||||
websiteUrl: ""
|
||||
}
|
||||
]
|
||||
|
||||
Component.onCompleted: append(data)
|
||||
}
|
|
@ -3,14 +3,35 @@ pragma Singleton
|
|||
import QtQuick 2.15
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
readonly property int ethNet: 1
|
||||
readonly property int optimismNet: 2
|
||||
readonly property int arbitrumNet: 3
|
||||
readonly property int optimismNet: 10
|
||||
readonly property int arbitrumNet: 42161
|
||||
readonly property int hermezNet: 4
|
||||
readonly property int testnetNet: 5
|
||||
readonly property int customNet: 6
|
||||
|
||||
function getChainName(chainId) {
|
||||
if(chainId === root.ethNet)
|
||||
return "Mainnet"
|
||||
|
||||
if(chainId === root.optimismNet)
|
||||
return "Optimism"
|
||||
|
||||
if(chainId === root.arbitrumNet)
|
||||
return "Arbitrum"
|
||||
|
||||
if(chainId === root.hermezNet)
|
||||
return "Hermez"
|
||||
|
||||
if(chainId === root.testnetNet)
|
||||
return "Goerli"
|
||||
|
||||
if(chainId === root.customNet)
|
||||
return "Custom"
|
||||
}
|
||||
|
||||
component CustomNetworkModel: ListModel {
|
||||
// Simulate Nim's way of providing access to data
|
||||
function rowData(index, propName) {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import Models 1.0
|
||||
|
||||
ListModel {
|
||||
id: root
|
||||
|
||||
readonly property string uniswap: "uniswap"
|
||||
readonly property string status: "status"
|
||||
readonly property string custom: "custom"
|
||||
|
||||
readonly property var data: [
|
||||
{
|
||||
key: root.uniswap,
|
||||
name: "Uniswap Labs Default",
|
||||
updatedAt: 1695720962,
|
||||
source: "https://gateway.ipfs.io/ipns/tokens.uniswap.org",
|
||||
version: "11.6.0",
|
||||
tokensCount: 731,
|
||||
image: ModelsData.assets.uni
|
||||
},
|
||||
{
|
||||
key: root.status,
|
||||
name: "Status Token List",
|
||||
updatedAt: 1661506562,
|
||||
source: "https://status.im/",
|
||||
version: "11.6.0",
|
||||
tokensCount: 250,
|
||||
image: ModelsData.assets.snt
|
||||
}
|
||||
]
|
||||
|
||||
Component.onCompleted: append(data)
|
||||
}
|
|
@ -5,18 +5,21 @@ BannerModel 1.0 BannerModel.qml
|
|||
ChannelsModel 1.0 ChannelsModel.qml
|
||||
CollectiblesModel 1.0 CollectiblesModel.qml
|
||||
FeesModel 1.0 FeesModel.qml
|
||||
FlatTokensModel 1.0 FlatTokensModel.qml
|
||||
IconModel 1.0 IconModel.qml
|
||||
LinkPreviewModel 1.0 LinkPreviewModel.qml
|
||||
MintedTokensModel 1.0 MintedTokensModel.qml
|
||||
RecipientModel 1.0 RecipientModel.qml
|
||||
SourceOfTokensModel 1.0 SourceOfTokensModel.qml
|
||||
TokenHoldersModel 1.0 TokenHoldersModel.qml
|
||||
UsersModel 1.0 UsersModel.qml
|
||||
WalletSendAccountsModel 1.0 WalletSendAccountsModel.qml
|
||||
WalletAccountsModel 1.0 WalletAccountsModel.qml
|
||||
WalletAssetsModel 1.0 WalletAssetsModel.qml
|
||||
WalletCollectiblesModel 1.0 WalletCollectiblesModel.qml
|
||||
WalletKeyPairModel 1.0 WalletKeyPairModel.qml
|
||||
WalletNestedCollectiblesModel 1.0 WalletNestedCollectiblesModel.qml
|
||||
|
||||
singleton ModelsData 1.0 ModelsData.qml
|
||||
singleton NetworksModel 1.0 NetworksModel.qml
|
||||
singleton PermissionsModel 1.0 PermissionsModel.qml
|
||||
WalletSendAccountsModel 1.0 WalletSendAccountsModel.qml
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
import shared.controls 1.0
|
||||
import utils 1.0
|
||||
|
||||
import AppLayouts.Profile.popups 1.0
|
||||
|
||||
StatusListView {
|
||||
id: root
|
||||
|
||||
required property var sourcesOfTokensModel // Expected roles: key, name, updatedAt, source, version, tokensCount, image
|
||||
required property var tokensListModel // Expected roles: name, symbol, image, chainName, explorerUrl
|
||||
|
||||
signal itemClicked(string key)
|
||||
|
||||
model: root.sourcesOfTokensModel
|
||||
spacing: 8
|
||||
delegate: StatusListItem {
|
||||
height: 76
|
||||
width: parent.width
|
||||
title: model.name
|
||||
subTitle: qsTr("%n token(s) · Last updated %1 @%2",
|
||||
"",
|
||||
model.tokensCount).arg(LocaleUtils.formatDate(model.updatedAt * 1000)).arg(LocaleUtils.formatTime(model.updatedAt, Locale.ShortFormat))
|
||||
asset.name: model.image
|
||||
asset.isImage: true
|
||||
border.width: 1
|
||||
border.color: Theme.palette.baseColor5
|
||||
components: [
|
||||
StatusButton {
|
||||
text: qsTr("View")
|
||||
|
||||
onClicked: keyFilter.value = model.key
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
footer: Item {
|
||||
width: parent.width
|
||||
height: root.count > 0 ? shapeRect.implicitHeight + 40 : shapeRect.implicitHeight
|
||||
|
||||
ShapeRectangle {
|
||||
id: shapeRect
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width - 4 // The rectangular path is rendered outside
|
||||
|
||||
icon: "add"
|
||||
text: qsTr("Add Token List (coming soon)")
|
||||
}
|
||||
}
|
||||
|
||||
Instantiator {
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: sourcesOfTokensModel
|
||||
|
||||
filters: ValueFilter {
|
||||
id: keyFilter
|
||||
|
||||
roleName: "key"
|
||||
value : ""
|
||||
}
|
||||
}
|
||||
|
||||
delegate: QtObject {
|
||||
id: delegate
|
||||
|
||||
required property string name
|
||||
required property string image
|
||||
required property string source
|
||||
required property int updatedAt
|
||||
required property string version
|
||||
required property int tokensCount
|
||||
|
||||
readonly property TokenListPopup popup: TokenListPopup {
|
||||
parent: root
|
||||
|
||||
sourceName: delegate.name
|
||||
sourceImage: delegate.image
|
||||
sourceUrl: delegate.source
|
||||
sourceUpdatedAt: delegate.updatedAt
|
||||
sourceVersion: delegate.version
|
||||
tokensCount: delegate.tokensCount
|
||||
|
||||
tokensListModel: SortFilterProxyModel {
|
||||
sourceModel: root.tokensListModel
|
||||
|
||||
// Filter by source
|
||||
filters: ExpressionFilter {
|
||||
expression: (model.jsArraySources).includes(keyFilter.value)
|
||||
}
|
||||
}
|
||||
|
||||
onLinkClicked: Global.openLink(link)
|
||||
onClosed: keyFilter.value = ""
|
||||
Component.onCompleted: open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,3 +3,4 @@ ProfileShowcaseCommunitiesPanel 1.0 ProfileShowcaseCommunitiesPanel.qml
|
|||
ProfileShowcaseCollectiblesPanel 1.0 ProfileShowcaseCollectiblesPanel.qml
|
||||
ProfileShowcaseAccountsPanel 1.0 ProfileShowcaseAccountsPanel.qml
|
||||
ProfileShowcaseAssetsPanel 1.0 ProfileShowcaseAssetsPanel.qml
|
||||
SupportedTokenListsPanel 1.0 SupportedTokenListsPanel.qml
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQml.Models 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import shared.panels 1.0
|
||||
|
||||
StatusDialog {
|
||||
id: root
|
||||
|
||||
required property string sourceName
|
||||
required property string sourceImage
|
||||
required property string sourceUrl
|
||||
required property int sourceUpdatedAt
|
||||
required property string sourceVersion
|
||||
required property int tokensCount
|
||||
required property var tokensListModel // Expected roles: name, symbol, image, chainName, explorerUrl
|
||||
|
||||
signal linkClicked(string link)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property int symbolColumnWidth: 90
|
||||
readonly property int addressColumnWidth: 106
|
||||
readonly property int externalLinkBtnWidth: 32
|
||||
}
|
||||
|
||||
width: 521 // by design
|
||||
padding: 0
|
||||
horizontalPadding: Style.current.padding
|
||||
|
||||
contentItem: StatusListView {
|
||||
id: list
|
||||
|
||||
topMargin: Style.current.padding
|
||||
bottomMargin: Style.current.padding
|
||||
implicitHeight: contentHeight
|
||||
|
||||
model: root.tokensListModel
|
||||
header: ColumnLayout {
|
||||
spacing: 20
|
||||
width: list.width
|
||||
|
||||
CustomSourceInfoComponent {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Style.current.padding
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
CustomHeaderDelegate {}
|
||||
}
|
||||
delegate: CustomDelegate {}
|
||||
}
|
||||
|
||||
header: StatusDialogHeader {
|
||||
headline.title: qsTr("%1 Token List").arg(root.sourceName)
|
||||
headline.subtitle: qsTr("%n token(s)", "", root.tokensCount)
|
||||
actions.closeButton.onClicked: root.close()
|
||||
leftComponent: StatusSmartIdenticon {
|
||||
asset.name: root.sourceImage
|
||||
asset.isImage: !!asset.name
|
||||
}
|
||||
}
|
||||
|
||||
footer: StatusDialogFooter {
|
||||
spacing: Style.current.padding
|
||||
rightButtons: ObjectModel {
|
||||
StatusButton {
|
||||
text: qsTr("Done")
|
||||
type: StatusBaseButton.Type.Normal
|
||||
|
||||
onClicked: close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component CustomTextBlock: ColumnLayout {
|
||||
id: textBlock
|
||||
|
||||
property string title
|
||||
property string text
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: textBlock.title
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: textBlock.text
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
|
||||
component CustomExternalLinkButton: StatusFlatButton {
|
||||
id: extButton
|
||||
|
||||
property string link
|
||||
|
||||
Layout.preferredHeight: d.externalLinkBtnWidth
|
||||
Layout.preferredWidth: d.externalLinkBtnWidth
|
||||
|
||||
spacing: 0
|
||||
textColor: Theme.palette.baseColor1
|
||||
textHoverColor: Theme.palette.directColor1
|
||||
icon.name: "external-link"
|
||||
onClicked: root.linkClicked(root.sourceUrl)
|
||||
}
|
||||
|
||||
component CustomSourceInfoComponent: ColumnLayout {
|
||||
spacing: 20
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.current.padding
|
||||
|
||||
CustomTextBlock {
|
||||
title: qsTr("Source")
|
||||
text: root.sourceUrl
|
||||
}
|
||||
|
||||
CustomExternalLinkButton {
|
||||
Layout.rightMargin: Style.current.halfPadding
|
||||
|
||||
link: root.sourceUrl
|
||||
}
|
||||
}
|
||||
|
||||
CustomTextBlock {
|
||||
title: qsTr("Version")
|
||||
text: root.sourceVersion
|
||||
}
|
||||
|
||||
CustomTextBlock {
|
||||
title: qsTr("Automatically updates")
|
||||
text: qsTr("Last updated %n day(s) ago",
|
||||
"",
|
||||
LocaleUtils.daysBetween(root.sourceUpdatedAt * 1000, Date.now()))
|
||||
}
|
||||
}
|
||||
|
||||
component CustomHeaderDelegate: RowLayout {
|
||||
height: 34
|
||||
width: contentItem.width
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
|
||||
text: qsTr("Name")
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.preferredWidth: d.symbolColumnWidth - Layout.leftMargin
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
|
||||
text: qsTr("Symbol")
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.preferredWidth: d.addressColumnWidth - Layout.leftMargin
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
|
||||
text: qsTr("Address")
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
// Just a filler corresponding to external link column
|
||||
Item {
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.preferredWidth: d.externalLinkBtnWidth
|
||||
Layout.rightMargin: Style.current.bigPadding
|
||||
}
|
||||
}
|
||||
|
||||
component CustomDelegate: Rectangle {
|
||||
width: contentItem.width
|
||||
height: 64
|
||||
color: (sensor.containsMouse || externalLinkBtn.hovered) ? Theme.palette.baseColor2 : "transparent"
|
||||
radius: 8
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
spacing: Style.current.padding
|
||||
|
||||
StatusSmartIdenticon {
|
||||
asset.isImage: true
|
||||
asset.name: model.image
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: model.name
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: model.chainName
|
||||
elide: Text.ElideMiddle
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.preferredWidth: d.symbolColumnWidth - Layout.leftMargin
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
|
||||
text: model.symbol
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.preferredWidth: d.addressColumnWidth - Layout.leftMargin
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
|
||||
text: model.address
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
CustomExternalLinkButton {
|
||||
id: externalLinkBtn
|
||||
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.bigPadding
|
||||
|
||||
link: model.explorerUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,8 @@ SetupSyncingPopup 1.0 SetupSyncingPopup.qml
|
|||
AddSocialLinkModal 1.0 AddSocialLinkModal.qml
|
||||
ModifySocialLinkModal 1.0 ModifySocialLinkModal.qml
|
||||
RenameKeypairPopup 1.0 RenameKeypairPopup.qml
|
||||
WalletKeypairAccountMenu 1.0 WalletKeypairAccountMenu.qml
|
||||
WalletAddressMenu 1.0 WalletAddressMenu.qml
|
||||
RenameAccontModal 1.0 RenameAccontModal.qml
|
||||
RemoveKeypairPopup 1.0 RemoveKeypairPopup.qml
|
||||
TokenListPopup 1.0 TokenListPopup.qml
|
||||
WalletKeypairAccountMenu 1.0 WalletKeypairAccountMenu.qml
|
||||
WalletAddressMenu 1.0 WalletAddressMenu.qml
|
||||
|
|
|
@ -219,6 +219,9 @@ SettingsContentBase {
|
|||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
sourcesOfTokensModel: undefined//tokensStore.sourcesOfTokensModel
|
||||
tokensListModel: undefined//tokensStore.flatTokensModel
|
||||
}
|
||||
|
||||
DappPermissionsView {
|
||||
|
|
|
@ -5,9 +5,14 @@ import StatusQ.Controls 0.1
|
|||
|
||||
import shared.controls 1.0
|
||||
|
||||
import AppLayouts.Profile.panels 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
required property var sourcesOfTokensModel // Expected roles: key, name, updatedAt, source, version, tokensCount, image
|
||||
required property var tokensListModel // Expected roles: name, symbol, image, chainName, explorerUrl
|
||||
|
||||
StatusTabBar {
|
||||
id: tabBar
|
||||
|
||||
|
@ -54,12 +59,12 @@ ColumnLayout {
|
|||
text: qsTr("You’ll be able to manage the display of your collectibles here")
|
||||
}
|
||||
|
||||
// TO BE REPLACED: Empty placeholder when no token lists; dashed rounded rectangle
|
||||
ShapeRectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: parent.width - 4 // The rectangular path is rendered outside
|
||||
Layout.preferredHeight: 44
|
||||
text: qsTr("Token List (coming soon)")
|
||||
SupportedTokenListsPanel {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
sourcesOfTokensModel: root.sourcesOfTokensModel
|
||||
tokensListModel: root.tokensListModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue