feat(wallet2) Implementing new architecture proposal

Introducing stores, panels, views and controls in
order to implement the new architecture proposal in
WalletV2

Closes #3479
This commit is contained in:
Alexandra Betouni 2021-09-14 19:23:02 +03:00 committed by Iuri Matias
parent 9e742e4b4a
commit efbc8073e1
35 changed files with 2351 additions and 809 deletions

1512
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,14 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../imports"
import "../../../shared"
import "stores"
import "controls"
import "views"
import "panels"
import "popups"
import "views/assets"
import "."
import "./components"
import "views/collectibles"
import StatusQ.Controls 0.1
import StatusQ.Layout 0.1
@ -16,21 +20,10 @@ Item {
id: walletView
property bool hideSignPhraseModal: false
property RootStore store: RootStore { }
function showSavedAddressesView() {
layoutWalletTwoPanel.rightPanel.view.replace(cmpSavedAddresses);
}
function hideSavedAddressesView() {
layoutWalletTwoPanel.rightPanel.view.replace(walletInfoContent);
}
function openCollectibleDetailView(options) {
collectiblesDetailPage.active = true
collectiblesDetailPage.item.show(options)
}
function showSigningPhrasePopup(){
function showSigningPhrasePopup() {
//TODO improve this to not use dynamic scoping
if(!hideSignPhraseModal && !appSettings.hideSignPhraseModal){
signPhrasePopup.open();
}
@ -38,12 +31,18 @@ Item {
SignPhraseModal {
id: signPhrasePopup
signingPhraseText: walletView.store.walletModelInst.utilsView.signingPhrase
onRemindLaterButtonClicked: {
hideSignPhraseModal = true;
signPhrasePopup.close();
}
}
SeedPhraseBackupWarning {
SeedPhraseBackupWarningPanel {
id: seedPhraseWarning
width: parent.width
anchors.top: parent.top
visible: !walletView.store.profileModelInst.mnemonic.isBackedUp
}
StatusAppTwoPanelLayout {
@ -53,15 +52,23 @@ Item {
width: walletView.width
Component.onCompleted: {
if(onboardingModel.firstTimeLogin){
onboardingModel.firstTimeLogin = false
walletModel.setInitialRange()
if (walletView.store.onboardingModelInst.firstTimeLogin) {
walletView.store.onboardingModelInst.firstTimeLogin = false;
walletView.store.walletModelInst.setInitialRange();
}
}
leftPanel: LeftTab {
leftPanel: LeftTabView {
id: leftTab
anchors.fill: parent
store: walletView.store
onSavedAddressesClicked: {
if (selected) {
stackView.replace(cmpSavedAddresses);
} else {
stackView.replace(walletInfoContent);
}
}
}
rightPanel: Item {
@ -76,7 +83,6 @@ Item {
anchors.left: parent.left
anchors.leftMargin: 80
anchors.right: parent.right
visible: !collectiblesDetailPage.active
anchors.rightMargin: 80
StackBaseView {
id: stackView
@ -84,9 +90,16 @@ Item {
Layout.fillHeight: true
initialItem: Item {
id: walletInfoContent
WalletHeader {
WalletHeaderPanel {
id: walletHeader
changeSelectedAccount: leftTab.changeSelectedAccount
accountsModel: walletView.store.walletModelV2Inst.accountsView.accounts
currentAccount: walletView.store.walletModelV2Inst.accountsView.currentAccount
qrCode: walletView.store.profileModelInst.qrCode(walletView.store.selectedAccount.address)
allNetworksModel: walletView.store.walletModelV2Inst.networksView.allNetworks
enabledNetworksModel: walletView.store.walletModelV2Inst.networksView.enabledNetworks
onCopyText: {
walletView.store.copyText(text);
}
}
TabBar {
id: walletTabBar
@ -96,9 +109,7 @@ Item {
anchors.topMargin: Style.current.padding
height: childrenRect.height
spacing: 24
background: Rectangle {
color: Style.current.transparent
}
background: null
StatusTabButton {
id: assetsBtn
btnText: qsTr("Assets")
@ -115,12 +126,7 @@ Item {
id: activityBtn
btnText: qsTr("Activity")
}
StatusTabButton {
id: settingsBtn
btnText: qsTr("Settings")
}
}
StackLayout {
id: stackLayout
anchors.top: walletTabBar.bottom
@ -141,6 +147,10 @@ Item {
}
CollectiblesView {
id: collectiblesTab
store: walletView.store
onCollectibleClicked: {
stackView.replace(collectibleDetailView);
}
}
ActivityView {
id: activityTab
@ -148,40 +158,38 @@ Item {
}
}
}
}
Component {
id: assetDetailView
AssetDetailView {
onBackPressed: {
stackView.replace(walletInfoContent);
}
SettingsTab {
id: settingsTab
}
Component {
id: assetDetailView
AssetDetailView {
onBackPressed: {
stackView.replace(walletInfoContent);
}
}
Component {
id: cmpSavedAddresses
SavedAddresses {}
}
Component {
id: collectibleDetailView
CollectibleDetailView {
store: walletView.store
onBackPressed: {
stackView.replace(walletInfoContent);
}
}
}
WalletFooter {
Component {
id: cmpSavedAddresses
SavedAddressesView {
store: walletView.store
}
}
WalletFooterPanel {
id: walletFooter
anchors.bottom: parent.bottom
}
Loader {
id: collectiblesDetailPage
anchors.bottom: walletFooter.top
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
active: false
sourceComponent: CollectibleDetailsPage {
anchors.fill: parent
}
walletV2Model: walletView.store.walletModelV2Inst
}
}
}

View File

@ -1,240 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Dialogs 1.3
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import StatusQ.Popups 0.1
StatusModal {
id: popup
height: (keyOrSeedPhraseInput.input.edit.contentHeight > 56 || seedPhraseInserted) ? 517 : 498
header.title: qsTr("Add account")
onOpened: {
keyOrSeedPhraseInput.input.edit.forceActiveFocus(Qt.MouseFocusReason);
}
property bool loading: false
property int marginBetweenInputs: 20
property bool seedPhraseInserted: false
property bool isSeedCountValid: false
signal addAccountClicked()
function seedPhraseNotFound() {
var seedValidationError = onboardingModel.validateMnemonic(keyOrSeedPhraseInput.text);
var regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
return regex.test(seedValidationError);
}
function validate() {
if (popup.isSeedCountValid && !popup.seedPhraseNotFound()) {
var validCount = 0;
var accountsList = seedAccountDetails.activeAccountsList;
for (var i = 0; i < accountsList.count; i++) {
if (accountsList.itemAtIndex(i).nameInputValid) {
validCount++;
}
}
}
return (popup.isSeedCountValid && !popup.seedPhraseNotFound()) ? (validCount === accountsList.count) :
(keyOrSeedPhraseInput.valid && pkeyAccountDetails.nameInputValid);
}
contentItem: Item {
id: contentItem
anchors.left: parent.left
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: 10
height: parent.height
Item {
id: leftContent
StatusInput {
id: keyOrSeedPhraseInput
width: parent.width
anchors.top: parent.top
anchors.topMargin: popup.marginBetweenInputs
input.multiline: true
input.icon.width: 15
input.icon.height: 11
input.icon.name: (popup.isSeedCountValid) || Utils.isPrivateKey(keyOrSeedPhraseInput.text) ? "checkmark" : ""
input.icon.color: Theme.palette.primaryColor1
input.leftIcon: false
input.implicitHeight: 56
input.placeholderText: qsTr("Enter private key or seed phrase")
label: qsTr("Private key or seed phrase")
validators: [
StatusValidator {
validate: function () {
return popup.seedPhraseInserted ? (popup.isSeedCountValid &&
!popup.seedPhraseNotFound()) : Utils.isPrivateKey(keyOrSeedPhraseInput.text);
}
}
]
onTextChanged: {
popup.seedPhraseInserted = keyOrSeedPhraseInput.text.includes(" ");
if (popup.seedPhraseInserted) {
popup.seedPhraseInserted = true;
seedAccountDetails.searching = true;
seedAccountDetails.timer.start();
}
popup.isSeedCountValid = (!!keyOrSeedPhraseInput.text && (keyOrSeedPhraseInput.text.match(/(\w+)/g).length === 12));
if (text === "") {
errorMessage = qsTr("You need to enter a valid private key or seed phrase");
} else {
if (!popup.seedPhraseInserted) {
errorMessage = !Utils.isPrivateKey(keyOrSeedPhraseInput.text) ?
qsTrId("enter-a-valid-private-key-(64-characters-hexadecimal-string)") : "";
} else {
if (!popup.isSeedCountValid) {
errorMessage = qsTrId("enter-a-valid-mnemonic");
} else if (popup.seedPhraseNotFound()) {
errorMessage = qsTrId("custom-seed-phrase") + '. ' + qsTrId("custom-seed-phrase-text-1");
} else {
errorMessage = "";
}
}
}
}
}
}
Rectangle {
id: separator
color: Theme.palette.statusPopupMenu.separatorColor
}
PKeyAccountDetails {
id: pkeyAccountDetails
width: parent.width
height: parent.height/2
anchors.top: separator.bottom
}
SeedAddAccountView {
id: seedAccountDetails
width: (parent.width/2)
height: parent.height
anchors.right: parent.right
}
states: [
State {
when: (popup.isSeedCountValid && !popup.seedPhraseNotFound())
PropertyChanges {
target: popup
width: 907
}
PropertyChanges {
target: pkeyAccountDetails
opacity: 0.0
}
PropertyChanges {
target: leftContent
width: contentItem.width/2
height: contentItem.height
}
PropertyChanges {
target: separator
width: 1
height: contentItem.height
}
AnchorChanges {
target: separator
anchors.left: leftContent.right
}
PropertyChanges {
target: seedAccountDetails
opacity: 1.0
}
},
State {
when: !(popup.isSeedCountValid && !popup.seedPhraseNotFound())
PropertyChanges {
target: popup
width: 574
}
PropertyChanges {
target: seedAccountDetails
opacity: 0.0
}
PropertyChanges {
target: leftContent
width: contentItem.width
height: 120
}
PropertyChanges {
target: pkeyAccountDetails
opacity: 1.0
}
PropertyChanges {
target: separator
width: contentItem.width
height: 1
anchors.topMargin: (2*popup.marginBetweenInputs)
}
AnchorChanges {
target: separator
anchors.left: contentItem.left
anchors.top: leftContent.bottom
}
}
]
}
rightButtons: [
StatusButton {
text: popup.loading ? qsTrId("loading") : qsTrId("add-account")
enabled: (!popup.loading && popup.validate())
MessageDialog {
id: accountError
title: qsTr("Adding the account failed")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
onClicked : {
popup.loading = true;
if (!popup.validate()) {
errorSound.play();
popup.loading = false;
} else {
//TODO account color to be verified with design
var result;
if (popup.isSeedCountValid && !popup.seedPhraseNotFound()) {
var accountsList = seedAccountDetails.activeAccountsList;
for (var i = 0; i < accountsList.count; i++) {
//TODO remove password requirement
if (!!accountsList.itemAtIndex(i)) {
result = walletModel.accountsView.addAccountsFromSeed(accountsList.itemAtIndex(i).accountAddress, "", accountsList.itemAtIndex(i).accountName, "")
}
}
} else {
result = walletModel.accountsView.addAccountsFromPrivateKey(keyOrSeedPhraseInput.text, "", pkeyAccountDetails.accountName, "");
}
popup.loading = false;
if (result) {
let resultJson = JSON.parse(result);
if (!Utils.isInvalidPasswordMessage(resultJson.error)) {
accountError.text = resultJson.error;
accountError.open();
}
errorSound.play();
return;
}
popup.addAccountClicked();
popup.close();
}
}
}
]
}

View File

@ -1 +0,0 @@
NetworkSelect 1.0 NetworkSelect.qml

View File

@ -1,5 +0,0 @@
AddAccount 1.0 AddAccount.qml
HeaderButton 1.0 HeaderButton.qml
CollectibleCollection 1.0 CollectibleCollection.qml
AddAccountPopup 1.0 AddAccountPopup.qml
CollectibleDetailsPage 1.0 CollectibleDetailsPage.qml

View File

@ -9,52 +9,15 @@ import StatusQ.Controls 0.1
Item {
id: collectiblesDetailHeader
height: childrenRect.height
property alias primaryText: collectibleName.text
property alias secondaryText: collectibleId.text
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
}
height: childrenRect.height
Layout.fillHeight: true
Layout.fillWidth: true
Row {
id: backButtonRow
anchors.top: parent.top
anchors.topMargin: 19
anchors.left: parent.left
spacing: 8
StatusIcon {
id: arrowIcon
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -1
icon: "chevron-up"
rotation: 270
color: Theme.palette.primaryColor1
}
StatusBaseText {
anchors.verticalCenter: parent.verticalCenter
id: collectiblesText
font.weight: Font.Medium
font.pixelSize: 15
lineHeight: 22
lineHeightMode: Text.FixedHeight
color: Theme.palette.primaryColor1
text: qsTr("Collectibles")
}
}
MouseArea {
anchors.fill: backButtonRow
onClicked: {
hide()
}
}
signal hideButtonClicked()
Row {
id: collectibleRow
@ -116,6 +79,6 @@ Item {
anchors.right: parent.right
icon.name: "send"
text: qsTr("Send")
onClicked: () => console.log("TODO");
onClicked: { console.log("TODO"); }
}
}

View File

@ -5,19 +5,20 @@ import "../../../../shared"
Rectangle {
property string text: ""
property url imageSource
property bool flipImage: false
property var onClicked: function () {}
id: headerButton
width: buttonImage.width + buttonText.width + Style.current.smallPadding * 2
+ (text === "" ? 0 : walletMenu.btnMargin)
+ (text === "" ? 0 : headerButton.btnMargin)
height: buttonText.height + Style.current.smallPadding * 2
border.width: 0
color: Style.current.transparent
radius: Style.current.radius
property int btnMargin
property string text: ""
property url imageSource
property bool flipImage: false
signal clicked()
SVGImage {
id: buttonImage
height: 18
@ -25,7 +26,7 @@ Rectangle {
anchors.leftMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: imageSource
source: headerButton.imageSource
rotation: flipImage ? 180 : 0
ColorOverlay {
@ -40,7 +41,7 @@ Rectangle {
visible: !!headerButton.text
text: headerButton.text
anchors.left: buttonImage.right
anchors.leftMargin: walletMenu.btnMargin
anchors.leftMargin: headerButton.btnMargin
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 13
font.family: Style.current.fontMedium.name
@ -51,15 +52,15 @@ Rectangle {
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
parent.color = Style.current.secondaryBackground
headerButton.color = Style.current.secondaryBackground;
}
onExited: {
parent.color = Style.current.transparent
headerButton.color = Style.current.transparent;
}
onClicked: {
headerButton.onClicked()
headerButton.clicked();
}
cursorShape: Qt.PointingHandCursor
}
}

View File

@ -9,12 +9,11 @@ import StatusQ.Controls 0.1
Item {
id: addEditError
property alias text: label.text
anchors.left: parent.left
anchors.right: parent.right
property alias text: label.text
StatusIcon {
id: errorIcon
icon: "warning"

View File

@ -18,8 +18,8 @@ Item {
property string accountName: accountNameInput.text
property bool nameInputValid: accountNameInput.valid
property string accountAddress: model.address
property string emoji: "" //TODO implement emoji selection
signal deleteClicked()
RowLayout {
anchors.fill: parent
@ -82,7 +82,7 @@ Item {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
walletModel.accountsView.deleteAccount(address);
root.deleteClicked();
}
}
}

View File

@ -8,14 +8,13 @@ Rectangle {
width: btnImage.width + btnImage.anchors.leftMargin + btnImage.anchors.rightMargin +
btnText.width + btnText.anchors.leftMargin + btnText.anchors.rightMargin
height: btnText.height + Style.current.smallPadding * 2
border.width: 0
color: Style.current.transparent
radius: Style.current.radius
property string text: ""
property url imageSource
property bool flipImage: false
property var onClicked: function () {}
signal clicked()
SVGImage {
id: btnImage
@ -51,15 +50,15 @@ Rectangle {
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
parent.color = Style.current.secondaryBackground
parent.color = Style.current.secondaryBackground;
}
onExited: {
parent.color = Style.current.transparent
parent.color = Style.current.transparent;
}
onClicked: {
walletBtnRoot.onClicked()
walletBtnRoot.clicked();
}
cursorShape: Qt.PointingHandCursor
}
}

View File

@ -1,15 +1,17 @@
import QtQuick 2.13
import "../../../../../shared"
import "../../../../../imports"
import "../../../../shared"
import "../../../../imports"
Grid {
id: root
columns: 2
spacing: 2
visible: (chainRepeater.count > 0)
property var model
Repeater {
id: chainRepeater
model: walletV2Model.networksView.enabledNetworks
model: root.model
width: parent.width
height: parent.height
@ -29,4 +31,4 @@ Grid {
}
}
}
}
}

View File

@ -1,11 +1,14 @@
import QtQuick 2.13
import "../../../../../shared"
import "../../../../../imports"
import "../../../../shared"
import "../../../../imports"
import "../popups"
Item {
id: root
width: selectRectangle.width
height: childrenRect.height
property var allNetworks
property var enabledNetworks
Rectangle {
id: selectRectangle
@ -41,23 +44,26 @@ Item {
cursorShape: Qt.PointingHandCursor
onClicked: {
if (selectPopup.opened) {
selectPopup.close()
return
selectPopup.close();
return;
}
selectPopup.open()
selectPopup.open();
}
}
NetworkFilter {
id: networkFilter
NetworkFilterPanel {
id: networkFilterPanel
width: root.width
anchors.topMargin: Style.current.halfPadding
anchors.top: selectRectangle.bottom
width: root.width
model: root.enabledNetworks
}
NetworkSelectPopup {
id: selectPopup
x: (parent.width - width)
y: (root.height - networkFilter.height)
y: (root.height - networkFilterPanel.height)
model: root.allNetworks
}
}

View File

@ -25,11 +25,13 @@ Item {
input.implicitHeight: 56
input.placeholderText: qsTrId("enter-an-account-name...")
label: qsTrId("account-name")
validators: [StatusMinLengthValidator { minLength: 1 }]
onTextChanged: {
errorMessage = (accountNameInput.text === "") ?
qsTrId("you-need-to-enter-an-account-name") : ""
}
validators: [
StatusMinLengthValidator {
minLength: 1
errorMessage: (accountNameInput.errors) ?
qsTrId("you-need-to-enter-an-account-name") : ""
}
]
}
Item {
//emoji placeholder

View File

@ -2,14 +2,13 @@ import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import "../../../imports"
import "../../../shared"
import "../Profile/Sections"
import "../../../../imports"
import "../../../../shared"
import "../../Profile/Sections"
import "."
Rectangle {
id: root
visible: !profileModel.mnemonic.isBackedUp
height: visible ? 32 : 0
color: Style.current.red
@ -19,55 +18,54 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
StyledText {
//% "Back up your seed phrase"
text: qsTrId("back-up-your-seed-phrase")
font.pixelSize: 13
anchors.verticalCenter: parent.verticalCenter
color: Style.current.white
font.pixelSize: 13
text: qsTrId("back-up-your-seed-phrase")
}
Button {
Control {
width: 58
height: 24
contentItem: Item {
anchors.fill: parent
Text {
text: "Back up"
font.pixelSize: 13
font.weight: Font.Medium
font.family: Style.current.fontRegular.name
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
color: Style.current.white
}
}
background: Rectangle {
radius: 4
anchors.fill: parent
border.color: Style.current.white
color: "#19FFFFFF"
}
contentItem: Item {
anchors.fill: parent
Text {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 13
font.weight: Font.Medium
font.family: Style.current.fontRegular.name
color: Style.current.white
text: "Back up"
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: backupSeedModal.open()
onClicked: { backupSeedModal.open(); }
}
}
}
SVGImage {
id: closeImg
height: 20
width: 20
anchors.top: parent.top
anchors.topMargin: 6
anchors.right: parent.right
anchors.rightMargin: 18
source: "../../img/close-white.svg"
height: 20
width: 20
source: "../../../img/close-white.svg"
}
ColorOverlay {
anchors.fill: closeImg
@ -88,5 +86,4 @@ Rectangle {
BackupSeedModal {
id: backupSeedModal
}
}

View File

@ -1,15 +1,16 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import "../../../imports"
import "./components"
import "../../../../imports"
import "../controls"
import "../popups"
Item {
id: walletFooterRoot
height: 50
width: parent.width
property var walletV2Model
Rectangle {
id: separatorLine
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@ -18,37 +19,37 @@ Item {
}
Row {
anchors.centerIn: parent
spacing: 50
WalletButton {
id: swapBtn
imageSource: "../../img/swap-icon.svg"
imageSource: "../../../img/swap-icon.svg"
text: qsTr("Swap")
onClicked: function (){
onClicked: {
console.log("TODO");
}
}
WalletButton {
id: sendBtn
imageSource: "../../img/send.svg"
imageSource: "../../../img/send.svg"
text: qsTr("Send")
onClicked: function (){
onClicked: {
console.log("TODO");
}
}
WalletButton {
id: buySellBtn
imageSource: "../../img/crypto-icon.svg"
imageSource: "../../../img/crypto-icon.svg"
text: qsTr("Buy / Sell")
onClicked: function (){
cryptoServicesModal.open()
onClicked: {
cryptoServicesModal.open();
}
}
}
CryptoServicesModal {
id: cryptoServicesModal
anchors.centerIn: parent
walletV2Model: walletFooterRoot.walletV2Model
}
}

View File

@ -1,11 +1,13 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../imports"
import "../../../shared"
import "../../../shared/status"
import "./components"
import "./components/network"
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "../controls"
import "../panels"
import "../popups"
Item {
id: walletHeader
@ -13,17 +15,25 @@ Item {
anchors.right: parent.right
height: walletAddress.y + walletAddress.height
property var currentAccount: walletV2Model.accountsView.currentAccount
property var changeSelectedAccount
property var qrCode
property var accountsModel
property var currentAccount
property var enabledNetworksModel
property var allNetworksModel
signal copyText(string text)
Row {
id: accountRow
anchors.top: parent.top
anchors.topMargin: 24
anchors.left: parent.left
anchors.leftMargin: 24
spacing: 8
StyledText {
id: title
anchors.verticalCenter: parent.verticalCenter
text: currentAccount.name
text: walletHeader.currentAccount.name
font.weight: Font.Medium
font.pixelSize: 28
}
@ -41,45 +51,48 @@ Item {
StyledText {
id: walletBalance
anchors.verticalCenter: parent.verticalCenter
text: currentAccount.balance.toUpperCase()
text: walletHeader.currentAccount.balance.toUpperCase()
font.pixelSize: 22
}
}
MouseArea {
anchors.fill: accountRow
cursorShape: Qt.PointingHandCursor
onClicked: {
//TOOD improve this to not use dynamic scoping
openPopup(shareModalComponent);
}
}
StatusExpandableAddress {
id: walletAddress
address: currentAccount.address
anchors.top: accountRow.bottom
anchors.left: accountRow.left
addressWidth: 180
address: walletHeader.currentAccount.address
}
NetworkSelect {
NetworkSelectPanel {
id: networkSelect
anchors.right: parent.right
allNetworks: walletHeader.allNetworksModel
enabledNetworks: walletHeader.enabledNetworksModel
}
Component {
id: shareModalComponent
ShareModal {
anchors.centerIn: parent
qrCode: walletHeader.qrCode
accountsModel: walletHeader.accountsModel
selectedAccount: walletHeader.currentAccount
onCopy: {
walletHeader.copyText(text);
}
onClosed: {
destroy();
this.destroy();
}
}
}
}
/*##^##
Designer {
D{i:0;formeditorColor:"#ffffff"}
}
##^##*/

View File

@ -0,0 +1,172 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Dialogs 1.3
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "../views"
import "../panels"
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
import StatusQ.Popups 0.1
StatusModal {
id: root
height: (keyOrSeedPhraseInput.input.edit.contentHeight > 56 || root.store.seedPhraseInserted) ? 517 : 498
header.title: qsTr("Add account")
property int marginBetweenInputs: 20
property var store
signal addAccountClicked()
onOpened: {
keyOrSeedPhraseInput.input.edit.forceActiveFocus(Qt.MouseFocusReason);
}
contentItem: Item {
id: contentItem
anchors.left: parent.left
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: 10
height: parent.height
Item {
id: leftContent
width: parent.width
height: parent.height/2
anchors.top: parent.top
anchors.topMargin: root.marginBetweenInputs
StatusInput {
id: keyOrSeedPhraseInput
anchors.fill: parent
input.multiline: true
input.icon.width: 15
input.icon.height: 11
input.icon.name: (root.store.isSeedCountValid) || Utils.isPrivateKey(keyOrSeedPhraseInput.text) ? "checkmark" : ""
input.icon.color: Theme.palette.primaryColor1
input.leftIcon: false
input.implicitHeight: 56
input.placeholderText: qsTr("Enter private key or seed phrase")
label: qsTr("Private key or seed phrase")
validators: [
StatusValidator {
validate: function (t) {
errorMessage = root.store.validateTextInput(t);
return ((t !== "") && ((root.store.isSeedCountValid && !root.store.seedPhraseNotFound(t))
|| Utils.isPrivateKey(t))) ? true : { actual: t }
}
}
]
onTextChanged: {
if (root.store.seedPhraseInserted) {
root.store.seedPhraseInserted = true;
seedAccountDetails.searching = true;
seedAccountDetails.timer.start();
}
}
}
}
Rectangle {
id: separator
color: Theme.palette.statusPopupMenu.separatorColor
}
PKeyAccountDetailsPanel {
id: pkeyAccountDetails
width: parent.width
height: parent.height/2
anchors.top: separator.bottom
}
SeedAddAccountView {
id: seedAccountDetails
width: (parent.width/2)
height: parent.height
anchors.right: parent.right
store: root.store
}
states: [
State {
when: (root.store.isSeedCountValid && !root.store.seedPhraseNotFound(keyOrSeedPhraseInput.text))
PropertyChanges {
target: root
width: 907
}
PropertyChanges {
target: pkeyAccountDetails
opacity: 0.0
}
PropertyChanges {
target: leftContent
width: contentItem.width/2
height: contentItem.height
}
PropertyChanges {
target: separator
width: 1
height: contentItem.height
}
AnchorChanges {
target: separator
anchors.left: leftContent.right
}
PropertyChanges {
target: seedAccountDetails
opacity: 1.0
}
},
State {
when: !(root.store.isSeedCountValid && !root.store.seedPhraseNotFound(keyOrSeedPhraseInput.text))
PropertyChanges {
target: root
width: 574
}
PropertyChanges {
target: seedAccountDetails
opacity: 0.0
}
PropertyChanges {
target: leftContent
width: contentItem.width
height: 120
}
PropertyChanges {
target: pkeyAccountDetails
opacity: 1.0
}
PropertyChanges {
target: separator
width: contentItem.width
height: 1
anchors.topMargin: (2*root.marginBetweenInputs)
}
AnchorChanges {
target: separator
anchors.left: contentItem.left
anchors.top: leftContent.bottom
}
}
]
}
rightButtons: [
StatusButton {
text: root.store.loadingAccounts ? qsTrId("loading") : qsTrId("add-account")
enabled: (!root.loadingAccounts && root.store.validateAddAccountPopup(keyOrSeedPhraseInput.text, seedAccountDetails.activeAccountsList,
keyOrSeedPhraseInput.valid, pkeyAccountDetails.nameInputValid))
onClicked : {
root.store.addAccount(keyOrSeedPhraseInput.text, seedAccountDetails.activeAccountsList,
keyOrSeedPhraseInput.valid, pkeyAccountDetails);
root.addAccountClicked();
root.close();
}
}
]
}

View File

@ -24,8 +24,8 @@ StatusModal {
addressInput.input.edit.forceActiveFocus(Qt.MouseFocusReason);
}
property var store
property bool loading: false
property var onBeforeSave: function() {}
property bool edit: false
property bool valid: addressInput.valid && nameInput.valid // TODO: Add network preference and emoji
property bool dirty: addressInput.input.dirty && nameInput.input.dirty
@ -34,6 +34,7 @@ StatusModal {
property int validationMode: edit ?
StatusInput.ValidationMode.Always :
StatusInput.ValidationMode.OnlyWhenDirty
signal beforeSave()
contentItem: Column {
anchors.left: parent.left
@ -125,10 +126,10 @@ StatusModal {
onClicked: {
root.loading = true;
root.onBeforeSave()
root.beforeSave();
edit ?
walletV2Model.savedAddressesView.editSavedAddress(name, address) :
walletV2Model.savedAddressesView.addSavedAddress(name, address);
root.store.walletModelV2Inst.savedAddressesView.editSavedAddress(name, address) :
root.store.walletModelV2Inst.savedAddressesView.addSavedAddress(name, address);
root.close()
root.loading = false;
}

View File

@ -6,22 +6,22 @@ import "../../../../shared/status"
ModalPopup {
id: root
title: root.name || qsTr("unnamed")
property string name: "Furbeard"
property string collectibleId: "1423"
property url imageUrl: ""
property string description: "Avast ye! I'm the dread pirate Furbeard, and I'll most likely sleep"
property string permalink: "https://www.cryptokitties.co/"
property var openModal: function (options) {
root.name = options.name
root.collectibleId = options.collectibleId
root.description = options.description
root.imageUrl = options.imageUrl
root.permalink = options.permalink
root.open()
root.name = options.name;
root.collectibleId = options.collectibleId;
root.description = options.description;
root.imageUrl = options.imageUrl;
root.permalink = options.permalink;
root.open();
}
title: root.name || qsTr("unnamed")
Item {
width: parent.width
@ -30,28 +30,26 @@ ModalPopup {
width: 248
height: 248
anchors.horizontalCenter: parent.horizontalCenter
source: root.imageUrl
radius: 16
fillMode: Image.PreserveAspectCrop
source: root.imageUrl
}
TextWithLabel {
id: idText
anchors.top: collectibleImage.bottom
label: qsTr("id")
text: root.collectibleId
anchors.top: collectibleImage.bottom
anchors.topMargin:0
}
TextWithLabel {
id: description
anchors.top: idText.bottom
visible: !!root.description
wrap: true
label: qsTr("description")
text: root.description
anchors.top: idText.bottom
anchors.topMargin: 0
wrap: true
}
}
@ -59,10 +57,10 @@ ModalPopup {
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
text: qsTr("View in Opensea")
anchors.top: parent.top
onClicked: {
appMain.openLink(root.permalink)
root.close()
//TOOD improve this to not use dynamic scoping
appMain.openLink(root.permalink);
root.close();
}
}
}

View File

@ -3,22 +3,27 @@ import QtQuick.Controls 2.14
import "../../../../imports"
import "../../../../shared"
import StatusQ.Popups 0.1
import StatusQ.Components 0.1
ModalPopup {
import "../controls"
StatusModal {
id: cryptoServicesPopupRoot
title: qsTr("Buy crypto")
height: 400
header.title: qsTr("Buy crypto")
property var walletV2Model
onOpened: {
loader.active = true
walletV2Model.cryptoServiceController.fetchCryptoServices()
loader.active = true;
cryptoServicesPopupRoot.walletV2Model.cryptoServiceController.fetchCryptoServices();
}
Component.onCompleted: {
walletV2Model.cryptoServiceController.fetchCryptoServicesFetched.connect(function(){
loader.sourceComponent = servicesComponent
})
Connections {
target: cryptoServicesPopupRoot.walletV2Model.cryptoServiceController
function onFetchCryptoServicesFetched() {
loader.sourceComponent = servicesComponent;
}
}
Loader {
@ -50,7 +55,7 @@ ModalPopup {
anchors.bottom: parent.bottom
anchors.topMargin: Style.current.padding
width: parent.width
model: walletV2Model.cryptoServiceController.cryptoServiceModel
model: cryptoServicesPopupRoot.walletV2Model.cryptoServiceController.cryptoServiceModel
focus: true
spacing: Style.current.padding
clip: true
@ -99,8 +104,9 @@ ModalPopup {
cursorShape: Qt.PointingHandCursor
onClicked: {
appMain.openLink(siteUrl)
cryptoServicesPopupRoot.close()
//TOOD improve this to not use dynamic scoping
appMain.openLink(siteUrl);
cryptoServicesPopupRoot.close();
}
}
}

View File

@ -4,8 +4,8 @@ import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import "../../../../../imports"
import "../../../../../shared"
import "../../../../imports"
import "../../../../shared"
Popup {
id: popup
@ -13,6 +13,7 @@ Popup {
width: 360
height: 432
closePolicy: Popup.CloseOnEscape
property var model
background: Rectangle {
radius: Style.current.radius
@ -45,7 +46,7 @@ Popup {
Repeater {
id: chainRepeater
model: walletV2Model.networksView.allNetworks
model: popup.model
Item {
width: content.width

View File

@ -5,28 +5,25 @@ import StatusQ.Popups 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
import "../../../shared"
import "../../../../shared"
StatusModal {
id: shareModal
QtObject {
id: internal
property var selectedAccount: walletV2Model.accountsView.currentAccount
}
anchors.centerIn: parent
implicitWidth: 454
implicitHeight: 568
property var selectedAccount
property var accountsModel
property var qrCode
signal copy(string text)
// To-do Icon in header needs to be updated once emoji picker is ready
header.title: internal.selectedAccount.name
header.title: shareModal.selectedAccount.name
header.subTitle: qsTr("Basic address")
header.popupMenu: StatusPopupMenu {
id: accountPickerPopUp
Repeater {
id: repeaster
model: walletV2Model.accountsView.accounts
id: repeater
model: shareModal.accountsModel
delegate: Loader {
sourceComponent: accountPickerPopUp.delegate
onLoaded: {
@ -35,10 +32,10 @@ StatusModal {
item.action.iconSettings.name = "filled-account"
}
Connections {
enabled: !!item.action
target: item.action
enabled: (!!item && !!item.action)
target: enabled ? item.action : null
onTriggered: {
internal.selectedAccount = { address, name, iconColor, fiatBalance }
shareModal.selectedAccount = { address, name, iconColor, fiatBalance }
accountPickerPopUp.dismiss()
}
}
@ -58,7 +55,7 @@ StatusModal {
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: false
source: profileModel.qrCode(internal.selectedAccount.address)
source: shareModal.qrCode
StatusIcon {
width: 66
height: 66
@ -86,7 +83,7 @@ StatusModal {
StyledText {
anchors.horizontalCenter: parent.horizontalCenter
text: internal.selectedAccount.address
text: shareModal.selectedAccount.address
color: Theme.palette.directColor1
font.pixelSize: 13
font.weight: Font.Medium
@ -108,12 +105,11 @@ StatusModal {
spacing: 5
StatusRoundButton {
anchors.horizontalCenter: parent.horizontalCenter
icon.name: index === 0 ? "copy" : "link"
onClicked: {
if (index === 0) {
if (internal.selectedAccount.address) {
chatsModel.copyToClipboard(internal.selectedAccount.address)
if (shareModal.selectedAccount.address) {
shareModal.copy(shareModal.selectedAccount.address);
}
else {
// To-do Get link functionality
@ -123,7 +119,6 @@ StatusModal {
}
StyledText {
anchors.horizontalCenter: parent.horizontalCenter
text: index === 0 ? qsTr("Copy") : qsTr("Get link")
color: Theme.palette.primaryColor1
font.pixelSize: 13

View File

@ -1,95 +1,95 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../imports"
import "../../../shared"
import "../../../shared/status"
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status"
import "."
ModalPopup {
id: signPhrasePopup
//% "Signing phrase"
title: qsTrId("signing-phrase")
height: 390
closePolicy: Popup.NoAutoClose
property string signingPhraseText: ""
signal remindLaterButtonClicked()
Column {
anchors.left: parent.left
anchors.right: parent.right
StyledText {
height: (Style.current.padding * 3)
anchors.horizontalCenter: parent.horizontalCenter
//% "This is your signing phrase"
text: qsTrId("this-is-you-signing")
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 17
font.weight: Font.Bold
horizontalAlignment: Text.AlignHCenter
height: Style.current.padding * 3
text: qsTrId("this-is-you-signing")
}
StyledText {
anchors.horizontalCenter: parent.horizontalCenter
//% "You should see these 3 words before signing each transaction"
text: qsTrId("three-words-description")
font.pixelSize: 15
width: 330
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
height: Style.current.padding * 4
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 15
wrapMode: Text.WordWrap
text: qsTrId("three-words-description")
}
Rectangle {
color: Style.current.inputBackground
height: 44
width: parent.width
height: 44
color: Style.current.inputBackground
StyledText {
id: signingPhrase
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
text: walletModel.utilsView.signingPhrase
text: signPhrasePopup.signingPhraseText
}
}
Item {
height: 30
width: parent.width
height: 30
SVGImage {
width: 13.33
height: 13.33
sourceSize.height: height * 2
sourceSize.width: width * 2
sourceSize.height: (height * 2)
sourceSize.width: (width * 2)
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
fillMode: Image.PreserveAspectFit
source: "../../img/exclamation_outline.svg"
source: "../../../img/exclamation_outline.svg"
}
}
StyledText {
//% "If you see a different combination, cancel the transaction and sign out"
text: qsTrId("three-words-description-2")
width: parent.width
height: 18
anchors.horizontalCenter: parent.horizontalCenter
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
width: parent.width
font.pixelSize: 13
height: 18
color: Style.current.danger
anchors.horizontalCenter: parent.horizontalCenter
//% "If you see a different combination, cancel the transaction and sign out"
text: qsTrId("three-words-description-2")
}
}
footer: Item {
width: parent.width
height: btnRemindLater.height
StatusButton {
anchors.right: btnRemindLater.left
anchors.rightMargin: Style.current.padding
type: "secondary"
//% "Ok, got it"
text: qsTrId("ens-got-it")
type: "secondary"
onClicked: {
//TOOD improve this to not use dynamic scoping
appSettings.hideSignPhraseModal = true;
close();
}
@ -102,8 +102,7 @@ ModalPopup {
//% "Remind me later"
text: qsTrId("remind-me-later")
onClicked: {
hideSignPhraseModal = true;
close();
signPhrasePopup.remindLaterButtonClicked();
}
}
}

View File

@ -1,5 +0,0 @@
LeftTab 1.0 LeftTab.qml
WalletHeader 1.0 WalletHeader.qml
AssetsTab 1.0 AssetsTab.qml
CollectiblesTab 1.0 CollectiblesTab.qml
SettingsTab SettingsTab.qml

View File

@ -0,0 +1,19 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.3
import "../../../../imports"
QtObject {
id: root
property string name
property string collectibleId
property string description: qsTr("Collectibles")
property color backgroundColor: "transparent"
property url collectibleImageUrl
property url permalink
property url imageUrl
property var properties
property var rankings
property var stats
property int collectionIndex
}

View File

@ -0,0 +1,212 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.3
import "../../../../imports"
QtObject {
id: root
property CollectiblesStore collectiblesStore: CollectiblesStore { }
property var walletModelInst: walletModel
property var walletModelV2Inst: walletV2Model
property var profileModelInst: profileModel
property var chatsModelInst: chatsModel
property var onboardingModelInst: onboardingModel
property int selectedAccount: 0
function getSavedAddressErrorText(savedAddresses, error) {
switch (error) {
case savedAddresses.Error.CreateSavedAddressError:
return qsTr("Error creating new saved address, please try again later.");
case savedAddresses.Error.DeleteSavedAddressError:
return qsTr("Error deleting saved address, please try again later.");
case savedAddresses.Error.ReadSavedAddressesError:
return qsTr("Error getting saved addresses, please try again later.");
case savedAddresses.Error.UpdateSavedAddressError:
return qsTr("Error updating saved address, please try again later.");
default: return "";
}
}
function copyText(text) {
root.chatsModelInst.copyToClipboard(text);
}
function changeSelectedAccount(newIndex) {
if (newIndex > root.walletModelV2Inst.accountsView.accounts) {
return;
}
root.selectedAccount = newIndex;
root.walletModelV2Inst.setCurrentAccountByIndex(newIndex);
}
function afterAddAccount() {
changeSelectedAccount(walletModelInst.accountsView.accounts.rowCount() - 1);
}
function getCollectionMaxValue(traitType, value, maxValue, collectionIndex) {
if(maxValue !== "")
return parseInt(value) + qsTr(" of ") + maxValue;
else
return parseInt(value) + qsTr(" of ") +
walletModelV2Inst.collectiblesView.collections.getCollectionTraitMaxValue(collectionIndex, traitType).toString();
}
property bool seedPhraseInserted: false
property bool isSeedCountValid: false
property bool loadingAccounts: false
function seedPhraseNotFound(text) {
var seedValidationError = root.onboardingModelInst.validateMnemonic(text);
var regex = new RegExp('word [a-z]+ not found in the dictionary', 'i');
return regex.test(seedValidationError);
}
function validateAddAccountPopup(text, model, keyOrSeedValid, accountNameValid) {
if (root.isSeedCountValid && !root.seedPhraseNotFound(text)) {
var validCount = 0;
for (var i = 0; i < model.count; i++) {
if (!!model.itemAtIndex(i) && model.itemAtIndex(i).nameInputValid) {
validCount++;
}
}
}
return (root.isSeedCountValid && !root.seedPhraseNotFound(text)) ? (validCount === model.count) :
(keyOrSeedValid && accountNameValid);
}
function validateTextInput(text) {
root.seedPhraseInserted = text.includes(" ");
var errorMessage;
root.isSeedCountValid = (!!text && (text.match(/(\w+)/g).length === 12));
if (text === "") {
errorMessage = qsTr("You need to enter a valid private key or seed phrase");
} else {
if (!root.seedPhraseInserted) {
errorMessage = !Utils.isPrivateKey(text) ?
qsTrId("enter-a-valid-private-key-(64-characters-hexadecimal-string)") : "";
} else {
if (!root.isSeedCountValid) {
errorMessage = qsTrId("enter-a-valid-mnemonic");
} else if (root.seedPhraseNotFound(text)) {
errorMessage = qsTrId("custom-seed-phrase") + '. ' + qsTrId("custom-seed-phrase-text-1");
} else {
errorMessage = "";
}
}
}
return errorMessage;
}
function addAccount(text, model, keyOrSeedValid, accountNameInput) {
root.loadingAccounts = true;
if (!root.validateAddAccountPopup(text, model, keyOrSeedValid, accountNameInput.nameInputValid)) {
//TOOD improve this to not use dynamic scoping
errorSound.play();
root.loadingAccounts = false;
} else {
//TODO account color to be verified with design
var result;
if (root.isSeedCountValid && !root.seedPhraseNotFound(text)) {
for (var i = 0; i < model.count; i++) {
//TODO add authorization process when Authorization moadl is ready
if (!!model.itemAtIndex(i)) {
result = root.walletModelInst.accountsView.addAccountsFromSeed(model.itemAtIndex(i).accountAddress, "qwqwqw", model.itemAtIndex(i).accountName, "")
}
}
} else {
result = root.walletModelInst.accountsView.addAccountsFromPrivateKey(text, "qwqwqw", accountNameInput.text, "");
}
root.loadingAccounts = false;
if (result) {
let resultJson = JSON.parse(result);
if (!Utils.isInvalidPasswordMessage(resultJson.error)) {
accountError.text = resultJson.error;
accountError.open();
}
//TOOD improve this to not use dynamic scoping
errorSound.play();
return;
}
}
}
property MessageDialog accountError: MessageDialog {
id: accountError
title: qsTr("Adding the account failed")
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
}
function deleteAccount(address) {
walletModelInst.accountsView.deleteAccount(address);
}
property ListModel exampleWalletModel: ListModel {
id: exampleWalletModel
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
}
property string imgPath: Qt.resolvedUrl("../../../img/")
function img(name) {
return imgPath + name + ".svg";
}
}

View File

@ -5,6 +5,8 @@ import "../../../../shared"
import "../../../../shared/status"
import "../../../../imports"
import "../popups"
StatusFlatButton {
id: btnAdd
width: 138
@ -14,9 +16,7 @@ StatusFlatButton {
icon.name: "add"
icon.width: 14
icon.height: 14
readonly property var onAfterAddAccount: function() {
walletInfoContainer.changeSelectedAccount(walletModel.accountsView.accounts.rowCount() - 1);
}
property var store
onClicked: {
if (newAccountMenu.opened) {
@ -31,20 +31,18 @@ StatusFlatButton {
width: 260
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
Action {
//% "Generate an account"
text: qsTrId("generate-a-new-account")
icon.source: "../../../img/generate_account.svg"
icon.width: 19
icon.height: 19
onTriggered: console.log("TODO")
icon.source: "../../../img/generate_account.svg"
text: qsTrId("generate-a-new-account")
onTriggered: { console.log("TODO"); }
}
Action {
//% "Add a watch-only address"
text: qsTrId("add-a-watch-account")
icon.source: "../../../img/eye.svg"
icon.width: 19
icon.height: 19
onTriggered: console.log("TODO")
icon.source: "../../../img/eye.svg"
text: qsTrId("add-a-watch-account")
onTriggered: { console.log("TODO"); }
}
Action {
text: qsTr("Add with key or seed phrase")
@ -56,11 +54,11 @@ StatusFlatButton {
}
}
onAboutToShow: {
btnAdd.state = "pressed"
btnAdd.state = "pressed";
}
onAboutToHide: {
btnAdd.state = "default"
btnAdd.state = "default";
}
}
@ -70,7 +68,10 @@ StatusFlatButton {
sourceComponent: AddAccountPopup {
id: addAccountPopup
anchors.centerIn: parent
onAddAccountClicked: { btnAdd.onAfterAddAccount(); }
store: btnAdd.store
onAddAccountClicked: {
btnAdd.store.afterAddAccount();
}
onClosed: {
addAccountPopupLoader.active = false;
}

View File

@ -4,12 +4,17 @@ import QtGraphicalEffects 1.13
import "../../../../imports"
import "../../../../shared"
import "../../../../shared/status/core"
import "../components"
import "../popups"
import "collectibles"
import StatusQ.Components 0.1
Item {
id: collectiblesTab
id: root
width: parent.width
property var store
signal collectibleClicked()
Loader {
id: contentLoader
@ -17,26 +22,24 @@ Item {
height: parent.height
sourceComponent: {
if (walletV2Model.collectiblesView.isLoading) {
return loading
if (root.store.walletModelV2Inst.collectiblesView.isLoading) {
return loading;
}
if (walletV2Model.collectiblesView.collections.rowCount() == 0) {
return empty
if (root.store.walletModelV2Inst.collectiblesView.collections.rowCount() === 0) {
return empty;
}
return loaded
return loaded;
}
}
Component {
id: loading
Item {
StatusLoadingIndicator {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: 20
height: 20
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
@ -63,23 +66,29 @@ Item {
Column {
id: collectiblesSection
width: collectiblesTab.width
width: parent.width
Repeater {
id: collectionsRepeater
model: walletV2Model.collectiblesView.collections
StatusExpandableItem {
model: root.store.walletModelV2Inst.collectiblesView.collections
//model: 5
delegate: StatusExpandableItem {
width: parent.width - 156
anchors.horizontalCenter: parent.horizontalCenter
primaryText: model.name
image.source: model.imageUrl
type: StatusExpandableItem.Type.Secondary
expandableComponent: CollectibleCollection {
expandableComponent: CollectibleCollectionView {
store: root.store
slug: model.slug
collectionImageUrl: model.imageUrl
collectionIndex: model.index
anchors.left: parent.left
anchors.leftMargin: Style.current.bigPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.bigPadding
onCollectibleClicked: {
root.collectibleClicked();
}
}
}
}

View File

@ -5,32 +5,24 @@ import QtGraphicalEffects 1.13
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import "../../../imports"
import "../../../shared"
import "./components"
import "../../../../imports"
import "../../../../shared"
Rectangle {
id: walletInfoContainer
color: Style.current.secondaryMenuBackground
property int selectedAccount: 0
property var changeSelectedAccount: function(newIndex) {
if (newIndex > walletV2Model.accountsView.accounts) {
return
}
selectedAccount = newIndex
walletV2Model.setCurrentAccountByIndex(newIndex)
collectiblesDetailPage.active = false
}
property var store
signal savedAddressesClicked(bool selected)
StyledText {
id: title
//% "Wallet"
text: qsTrId("wallet")
anchors.top: parent.top
anchors.topMargin: Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
font.weight: Font.Bold
font.pixelSize: 17
text: qsTrId("wallet")
}
Item {
@ -46,19 +38,19 @@ Rectangle {
StyledTextEdit {
id: walletAmountValue
color: Style.current.textColor
text: Utils.toLocaleString("0.00", globalSettings.locale, {"currency": true}) + " " + "USD"
selectByMouse: true
cursorVisible: true
readOnly: true
anchors.left: parent.left
font.weight: Font.Medium
font.pixelSize: 30
//TOOD improve this to not use dynamic scoping
text: Utils.toLocaleString("0.00", globalSettings.locale, {"currency": true}) + " " + "USD"
}
StyledText {
id: totalValue
color: Style.current.secondaryText
//% "Total value"
text: qsTrId("wallet-total-value")
anchors.left: walletAmountValue.left
anchors.top: walletAmountValue.bottom
@ -72,25 +64,18 @@ Rectangle {
id: walletDelegate
Rectangle {
property bool selected: index === selectedAccount
property bool hovered
id: rectangle
height: 64
color: {
if (selected) {
return Style.current.menuBackgroundActive
}
if (hovered) {
return Style.current.backgroundHoverLight
}
return Style.current.transparent
}
radius: Style.current.radius
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
height: 64
property bool selected: (index === walletInfoContainer.store.selectedAccount)
property bool hovered
color: selected ? Style.current.menuBackgroundActive :
hovered ? Style.current.backgroundHoverLight
: Style.current.transparent
radius: Style.current.radius
SVGImage {
id: walletIcon
@ -100,7 +85,7 @@ Rectangle {
anchors.topMargin: Style.current.smallPadding
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
source: "../../img/walletIcon.svg"
source: "../../../img/walletIcon.svg"
}
ColorOverlay {
anchors.fill: walletIcon
@ -109,7 +94,6 @@ Rectangle {
}
StyledText {
id: walletName
text: name
elide: Text.ElideRight
anchors.right: walletBalance.left
anchors.rightMargin: Style.current.smallPadding
@ -121,11 +105,11 @@ Rectangle {
font.pixelSize: 15
font.weight: Font.Medium
color: Style.current.textColor
text: name
}
StyledText {
id: walletAddress
font.family: Style.current.fontHexRegular.name
text: address
anchors.right: parent.right
anchors.rightMargin: parent.width/2
elide: Text.ElideMiddle
@ -136,10 +120,10 @@ Rectangle {
font.weight: Font.Medium
color: Style.current.secondaryText
opacity: selected ? 0.7 : 1
text: address
}
StyledText {
id: walletBalance
text: isLoading ? "..." : Utils.toLocaleString(fiatBalance, globalSettings.locale, {"currency": true}) + " " + "USD"
anchors.top: parent.top
anchors.topMargin: Style.current.smallPadding
anchors.right: parent.right
@ -147,19 +131,20 @@ Rectangle {
font.pixelSize: 15
font.weight: Font.Medium
color: Style.current.textColor
text: isLoading ? "..." : Utils.toLocaleString(fiatBalance, globalSettings.locale, {"currency": true}) + " " + "USD"
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
rectangle.hovered = true
rectangle.hovered = true;
}
onExited: {
rectangle.hovered = false
rectangle.hovered = false;
}
onClicked: {
walletInfoContainer.changeSelectedAccount(index)
walletInfoContainer.store.changeSelectedAccount(index);
}
}
}
@ -181,9 +166,8 @@ Rectangle {
anchors.fill: parent
spacing: 5
boundsBehavior: Flickable.StopAtBounds
model: walletInfoContainer.store.walletModelV2Inst.accountsView.accounts
delegate: walletDelegate
ListModel {
id: exampleWalletModel
ListElement {
@ -263,17 +247,16 @@ Rectangle {
iconColor: "#7CDA00"
}
}
model: walletV2Model.accountsView.accounts
}
}
AddAccount {
AddAccountView {
id: addAccountButton
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.top: accountsList.bottom
anchors.topMargin: 31
store: walletInfoContainer.store
}
StatusNavigationListItem {
id: btnSavedAddresses
@ -286,15 +269,7 @@ Rectangle {
onClicked: {
selected = !selected;
selected ?
walletView.showSavedAddressesView() :
walletView.hideSavedAddressesView();
walletInfoContainer.savedAddressesClicked(selected);
}
}
}
/*##^##
Designer {
D{i:0;formeditorColor:"#ffffff";formeditorZoom:0.75;height:770;width:340}
}
##^##*/

View File

@ -2,9 +2,8 @@ import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../imports"
import "../../../shared"
import "./components"
import "../../../../imports"
import "../../../../shared"
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
@ -12,14 +11,17 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1
import "../popups"
import "../controls"
Item {
id: root
property bool loading: false
property int error: SavedAddresses.Error.None
property int error: SavedAddressesView.Error.None
anchors.leftMargin: 80
anchors.rightMargin: 80
anchors.topMargin: 62
property var store
enum Error {
CreateSavedAddressError,
@ -30,20 +32,6 @@ Item {
None
}
function getErrorText(error) {
switch (error) {
case SavedAddresses.Error.CreateSavedAddressError:
return qsTr("Error creating new saved address, please try again later.");
case SavedAddresses.Error.DeleteSavedAddressError:
return qsTr("Error deleting saved address, please try again later.");
case SavedAddresses.Error.ReadSavedAddressesError:
return qsTr("Error getting saved addresses, please try again later.");
case SavedAddresses.Error.UpdateSavedAddressError:
return qsTr("Error updating saved address, please try again later.");
default: return "";
}
}
Item {
id: header
anchors.left: parent.left
@ -75,14 +63,15 @@ Item {
}
Component {
id: addEditSavedAddress
AddEditSavedAddress {
AddEditSavedAddressPopup {
id: addEditModal
anchors.centerIn: parent
store: root.store
onClosed: {
destroy()
destroy();
}
onBeforeSave: function() {
root.loading = true
onBeforeSave: {
root.loading = true;
}
}
}
@ -95,10 +84,12 @@ Item {
rightPadding: 11
visible: !root.loading
onClicked: {
//TODO improve this to not use dynamic scoping
appMain.openPopup(addEditSavedAddress)
}
}
StatusLoadingIndicator {
anchors.centerIn: parent
visible: root.loading
color: Theme.palette.directColor4
}
@ -128,6 +119,7 @@ Item {
StatusRoundButton {
icon.name: "pencil"
visible: showButtons
//TODO improve this to not use dynamic scoping
onClicked: appMain.openPopup(addEditSavedAddress,
{
edit: true,
@ -182,7 +174,7 @@ Item {
text: qsTr("Delete")
onClicked: {
root.loading = true
walletV2Model.savedAddressesView.deleteSavedAddress(
root.store.walletModelV2Inst.savedAddressesView.deleteSavedAddress(
deleteAddressConfirm.address)
deleteAddressConfirm.close()
}
@ -191,28 +183,28 @@ Item {
}
Connections {
target: walletV2Model.savedAddressesView
target: root.store.walletModelV2Inst.savedAddressesView
onAddEditResultChanged: {
root.loading = false
let resultRaw = walletV2Model.savedAddressesView.addEditResult
let resultRaw = root.store.walletModelV2Inst.savedAddressesView.addEditResult
let result = JSON.parse(resultRaw)
if (result.o) {
root.error = SavedAddresses.Error.None
walletV2Model.savedAddressesView.loadSavedAddresses();
root.error = SavedAddressesView.Error.None
root.store.walletModelV2Inst.savedAddressesView.loadSavedAddresses();
} else {
root.error = parseInt(result.e)
}
}
}
Connections {
target: walletV2Model.savedAddressesView
target: root.store.walletModelV2Inst.savedAddressesView
onDeleteResultChanged: {
root.loading = false
let resultRaw = walletV2Model.savedAddressesView.deleteResult
let resultRaw = root.store.walletModelV2Inst.savedAddressesView.deleteResult
let result = JSON.parse(resultRaw)
if (result.o) {
root.error = SavedAddresses.Error.None
walletV2Model.savedAddressesView.loadSavedAddresses();
root.error = SavedAddressesView.Error.None
root.store.walletModelV2Inst.savedAddressesView.loadSavedAddresses();
deleteAddressConfirm.close();
} else {
root.error = parseInt(result.e)
@ -220,13 +212,13 @@ Item {
}
}
Connections {
target: walletV2Model.savedAddressesView
target: root.store.walletModelV2Inst.savedAddressesView
onLoadResultChanged: {
root.loading = false
let resultRaw = walletV2Model.savedAddressesView.loadResult
let resultRaw = root.store.walletModelV2Inst.savedAddressesView.loadResult
let result = JSON.parse(resultRaw)
if (result.o) {
root.error = SavedAddresses.Error.None
root.error = SavedAddressesView.Error.None
} else {
root.error = parseInt(result.e)
}
@ -237,8 +229,8 @@ Item {
id: errorMessage
anchors.top: header.bottom
anchors.topMargin: Style.current.padding
visible: root.error !== SavedAddresses.Error.None
text: getErrorText(root.error)
visible: root.error !== SavedAddressesView.Error.None
text: root.store.getSavedAddressErrorText(SavedAddressesView, root.error)
height: visible ? 36 : 0
}
@ -267,80 +259,13 @@ Item {
ListView {
id: listView
//model: root.store.exampleWalletModel
model: root.store.walletModelV2Inst.savedAddressesView.savedAddresses
clip: true
spacing: 5
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
delegate: delegateSavedAddress
ListModel {
id: exampleWalletModel
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
ListElement {
name: "Status account"
address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f"
isFavorite: false
}
ListElement {
name: "Test account 1"
address: "0x2Ef1...E0Ba"
isFavorite: false
}
ListElement {
name: "Status account 2"
address: "0x2Ef1...E0Ba"
isFavorite: true
}
}
model: walletV2Model.savedAddressesView.savedAddresses //exampleWalletModel
}
}
}
}

View File

@ -1,6 +1,8 @@
import QtQuick 2.13
import "../../../../imports"
import "../panels"
import "../controls"
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
@ -19,6 +21,7 @@ Item {
searching = false;
}
}
property var store
property var dummyModel: []
Column {
@ -45,13 +48,16 @@ Item {
anchors.bottomMargin: 10
clip: true
//TODO replace with active accounts model
model: walletModel.accountsView.accounts
model: root.store.walletModelInst.accountsView.accounts
delegate: SeedAccountDetailsDelegate {
deleteButtonVisible: (activeAccountsView.count > 1)
onDeleteClicked: {
root.store.deleteAccount(address);
}
}
}
AccountNotFound {
AccountNotFoundPanel {
id: accountNotFound
width: parent.width
anchors.verticalCenter: parent.verticalCenter

View File

@ -6,11 +6,12 @@ import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import "../../../imports"
import "../Profile/Sections"
import "../../../../imports"
import "../../Profile/Sections"
Item {
id: root
property var store
Column {
anchors.top:parent.top
@ -25,15 +26,15 @@ Item {
anchors.right: parent.right
anchors.rightMargin: 20
visible : (walletV2Model.accountsView.currentAccount.walletType !== Constants.seedWalletType) &&
(walletV2Model.accountsView.currentAccount.walletType !== Constants.watchWalletType) &&
(walletV2Model.accountsView.currentAccount.walletType !== Constants.keyWalletType)
visible : (root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.seedWalletType) &&
(root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.watchWalletType) &&
(root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.keyWalletType)
expandable: false
icon.name: "seed-phrase"
primaryText: qsTr("Back up seed phrase")
secondaryText: qsTr("Back up your seed phrase now to secure this account")
button.text: qsTr("Back up seed phrase")
button.enabled: !profileModel.mnemonic.isBackedUp
button.enabled: !root.store.profileModelInst.mnemonic.isBackedUp
button.onClicked: backupSeedModal.open()
}
@ -43,7 +44,7 @@ Item {
anchors.right: parent.right
anchors.rightMargin: 20
visible : walletV2Model.accountsView.currentAccount.walletType !== Constants.watchWalletType
visible : root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.watchWalletType
expandable: true
icon.name: "secret"
primaryText: qsTr("Account signing phrase")
@ -57,8 +58,8 @@ Item {
anchors.right: parent.right
anchors.rightMargin: 20
visible : (walletV2Model.accountsView.currentAccount.walletType === Constants.keyWalletType) ||
(walletV2Model.accountsView.currentAccount.walletType === Constants.seedWalletType)
visible : (root.store.walletModelV2Inst.accountsView.currentAccount.walletType === Constants.keyWalletType) ||
(root.store.walletModelV2Inst.accountsView.currentAccount.walletType === Constants.seedWalletType)
expandable: true
icon.name: "seed-phrase"
primaryText: qsTr("View private key")
@ -67,7 +68,7 @@ Item {
expandableComponent: notImplemented
button.onClicked: {
// To-do open enter password Modal
expanded = !expanded
expanded = !expanded;
}
}
@ -131,7 +132,7 @@ Item {
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
wrapMode: Text.Wrap
text: walletV2Model.settingsView.signingPhrase
text: root.store.walletModelV2Inst.settingsView.signingPhrase
}
}
Rectangle {

View File

@ -7,21 +7,20 @@ import StatusQ.Core.Theme 0.1
Item {
id: root
width: parent.width
height: contentLoader.height
property string slug: ""
property bool assetsLoaded: false
property string collectionImageUrl: ""
property int collectionIndex: -1
signal clicked()
width: parent.width
height: contentLoader.height
property var store
signal collectibleClicked()
Connections {
target: walletV2Model.collectiblesView.getAssetsList(root.slug)
target: root.store.walletV2ModelInst.collectiblesView.getAssetsList(root.slug)
onAssetsChanged: {
root.assetsLoaded = true
root.assetsLoaded = true;
}
}
@ -30,7 +29,6 @@ Item {
width: parent.width
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
sourceComponent: root.assetsLoaded ? loaded : loading
}
@ -43,7 +41,6 @@ Item {
StatusLoadingIndicator {
width: 20
height: 20
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
@ -60,7 +57,7 @@ Item {
spacing: 24
Repeater {
model: walletV2Model.collectiblesView.getAssetsList(root.slug)
model: root.store.walletV2ModelInst.collectiblesView.getAssetsList(root.slug)
StatusRoundedImage {
id: image
width: 146
@ -74,18 +71,18 @@ Item {
MouseArea {
anchors.fill: parent
onClicked: {
openCollectibleDetailView({collectibleImageUrl:collectionImageUrl,
name: model.name,
collectibleId: model.id,
description: model.description,
permalink: model.permalink,
imageUrl: model.imageUrl,
backgroundColor: model.backgroundColor,
properties: model.properties,
rankings: model.rankings,
stats: model.stats,
collectionIndex: root.collectionIndex
})
root.store.collectiblesStore.collectibleImageUrl = collectionImageUrl;
root.store.collectiblesStore.name = model.name;
root.store.collectiblesStore.collectibleId = model.id;
root.store.collectiblesStore.description = model.description;
root.store.collectiblesStore.permalink = model.permalink;
root.store.collectiblesStore.imageUrl = model.imageUrl;
root.store.collectiblesStore.backgroundColor = model.backgroundColor;
root.store.collectiblesStore.properties = model.properties;
root.store.collectiblesStore.rankings = model.rankings;
root.store.collectiblesStore.stats = model.stats;
root.store.collectiblesStore.collectionIndex = root.collectionIndex;
root.collectibleClicked();
}
}
}
@ -94,6 +91,6 @@ Item {
}
Component.onCompleted: {
walletV2Model.collectiblesView.loadAssets(walletV2Model.accountsView.currentAccount.address, root.slug)
root.store.walletV2ModelInst.collectiblesView.loadAssets(root.store.walletV2ModelInst.accountsView.currentAccount.address, root.slug);
}
}

View File

@ -7,54 +7,32 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
Item {
id: collectiblesDetailContainer
import "../"
import "../../controls"
property var assetProperties
property var assetRankings
property var assetStats
property int collectionIndex: -1
StackDetailBase {
id: root
backButtonText: "Collectibles"
function show(options) {
collectibleHeader.image.source = options.collectibleImageUrl
collectibleHeader.primaryText = options.name
collectibleHeader.secondaryText = options.collectibleId
collectibleimage.image.source = options.imageUrl
collectibleText.text = options.description
collectibleimage.color = options.backgroundColor
assetProperties = options.properties
assetRankings = options.rankings
assetStats = options.stats
collectionIndex = options.collectionIndex
}
function hide() {
active = false
}
function getCollectionMaxValue(traitType, value, maxValue) {
if(maxValue !== "")
return parseInt(value) + qsTr(" of ") + maxValue
else
return parseInt(value) + qsTr(" of ") + walletV2Model.collectiblesView.collections.getCollectionTraitMaxValue(collectionIndex, traitType).toString()
}
property var store
property var assetStats: root.store.collectiblesStore.stats
property var assetRankings: root.store.collectiblesStore.rankings
property var assetProperties: root.store.collectiblesStore.properties
property int collectionIndex: root.store.collectiblesStore.collectionIndex
CollectibleDetailsHeader {
id: collectibleHeader
anchors.right: parent.right
anchors.rightMargin: 79
anchors.left: parent.left
anchors.leftMargin: 79
anchors.top: parent.top
anchors.right: parent.right
image.source: root.store.collectiblesStore.collectibleImageUrl
primaryText: root.store.collectiblesStore.name
secondaryText: root.store.collectiblesStore.collectibleId
}
Item {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: 83
anchors.right: parent.right
anchors.rightMargin: 78
anchors.top: collectibleHeader.bottom
anchors.topMargin: 46
@ -69,16 +47,17 @@ Item {
width: 253
height: 253
radius: 2
color: "transparent"
color: root.store.collectiblesStore.backgroundColor
border.color: Theme.palette.directColor8
border.width: 1
image.source: root.store.collectiblesStore.imageUrl
}
StatusBaseText {
id: collectibleText
width: parent.width - collectibleimage.width - 24
height: collectibleimage.height
text: qsTr("Collectibles")
text: root.store.collectiblesStore.description
color: Theme.palette.directColor1
font.pixelSize: 15
lineHeight: 22
@ -202,7 +181,7 @@ Item {
lineHeightMode: Text.FixedHeight
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
text: collectiblesDetailContainer.getCollectionMaxValue(model.traitType, model.value, model.maxValue)
text: root.store.getCollectionMaxValue(model.traitType, model.value, model.maxValue, collectionIndex)
}
}
}
@ -247,7 +226,7 @@ Item {
lineHeightMode: Text.FixedHeight
horizontalAlignment: Text.AlignLeft
elide: Text.ElideRight
text: collectiblesDetailContainer.getCollectionMaxValue(model.traitType, model.value, model.maxValue)
text: root.store.getCollectionMaxValue(model.traitType, model.value, model.maxValue, collectionIndex)
}
}
}