feat(@desktop/wallet): New Account header

fixes #10330
This commit is contained in:
Khushboo Mehta 2023-04-26 17:53:49 +02:00 committed by Khushboo-dev-cpp
parent ec04b8668f
commit a57c0b414b
25 changed files with 629 additions and 343 deletions

View File

@ -233,4 +233,10 @@ QtObject:
if item.getChainId() != chainId:
chainIds.add(item.getChainId())
return (chainIds, enable)
return (chainIds, enable)
proc getAllNetworksSupportedPrefix*(self: Model): string =
var networkString = ""
for item in self.items:
networkString = networkString & item.getShortName() & ':'
return networkString

View File

@ -124,6 +124,9 @@ QtObject:
proc getMainnetChainId*(self: View): int {.slot.} =
return self.layer1.getLayer1Network(self.areTestNetworksEnabled)
proc getAllNetworksSupportedPrefix*(self: View): string {.slot.} =
return self.all.getAllNetworksSupportedPrefix()
proc networkEnabledToUxEnabledState(enabled: bool, allEnabled: bool): UxEnabledState =
return if allEnabled:
UxEnabledState.AllEnabled
@ -133,4 +136,4 @@ proc networkEnabledToUxEnabledState(enabled: bool, allEnabled: bool): UxEnabledS
UxEnabledState.Disabled
proc areAllEnabled(networks: seq[NetworkDto]): bool =
return networks.allIt(it.enabled)
return networks.allIt(it.enabled)

View File

@ -8,6 +8,9 @@ type
balanceLoading: bool
color: string
emoji: string
# To do once we implement <All accounts> view
isAllAccounts: bool
hideWatchAccounts: bool
proc initItem*(
name: string = "",
@ -15,7 +18,9 @@ proc initItem*(
ens: string = "",
balanceLoading: bool = true,
color: string,
emoji: string
emoji: string,
isAllAccounts: bool = false,
hideWatchAccounts: bool = false
): Item =
result.name = name
result.mixedCaseAddress = mixedCaseAddress
@ -23,6 +28,8 @@ proc initItem*(
result.balanceLoading = balanceLoading
result.color = color
result.emoji = emoji
result.isAllAccounts = isAllAccounts
result.hideWatchAccounts = hideWatchAccounts
proc `$`*(self: Item): string =
result = fmt"""OverviewItem(
@ -32,6 +39,8 @@ proc `$`*(self: Item): string =
balanceLoading: {self.balanceLoading},
color: {self.color},
emoji: {self.emoji},
isAllAccounts: {self.isAllAccounts},
hideWatchAccounts: {self.hideWatchAccounts}
]"""
proc getName*(self: Item): string =
@ -52,3 +61,9 @@ proc getColor*(self: Item): string =
proc getEmoji*(self: Item): string =
return self.emoji
proc getIsAllAccounts*(self: Item): bool =
return self.isAllAccounts
proc getHideWatchAccounts*(self: Item): bool =
return self.hideWatchAccounts

View File

@ -16,6 +16,8 @@ QtObject:
balanceLoading: bool
color: string
emoji: string
isAllAccounts: bool
hideWatchAccounts: bool
proc setup(self: View) =
self.QObject.setup
@ -88,6 +90,20 @@ QtObject:
read = getEmoji
notify = emojiChanged
proc getIsAllAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.isAllAccounts)
proc isAllAccountsChanged(self: View) {.signal.}
QtProperty[QVariant] isAllAccounts:
read = getIsAllAccounts
notify = isAllAccountsChanged
proc getHideWatchAccounts(self: View): QVariant {.slot.} =
return newQVariant(self.hideWatchAccounts)
proc hideWatchAccountsChanged(self: View) {.signal.}
QtProperty[QVariant] hideWatchAccounts:
read = getHideWatchAccounts
notify = hideWatchAccountsChanged
proc setData*(self: View, item: Item) =
if(self.name != item.getName()):
self.name = item.getName()
@ -105,3 +121,9 @@ QtObject:
if(self.emoji != item.getEmoji()):
self.emoji = item.getEmoji()
self.emojiChanged()
if(self.isAllAccounts != item.getIsAllAccounts()):
self.isAllAccounts = item.getIsAllAccounts()
self.isAllAccountsChanged()
if(self.hideWatchAccounts != item.getHideWatchAccounts()):
self.hideWatchAccounts = item.getHideWatchAccounts()
self.hideWatchAccountsChanged()

View File

@ -289,4 +289,8 @@ ListModel {
title: "ProfileSocialLinksPanel"
section: "Panels"
}
ListElement {
title: "WalletHeader"
section: "Panels"
}
}

View File

@ -1,5 +1,6 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.13
import Storybook 1.0
import Models 1.0
@ -33,7 +34,6 @@ SplitView {
enabledNetworks: NetworksModel.enabledNetworks
allNetworks: enabledNetworks
isChainVisible: isChainVisibleCheckBox.checked
multiSelection: multiSelectionCheckBox.checked
}
}
@ -45,17 +45,10 @@ SplitView {
SplitView.fillWidth: true
Row {
CheckBox {
id: isChainVisibleCheckBox
text: "Is chain visible"
checked: true
}
CheckBox {
id: multiSelectionCheckBox
text: "Multi selection"
checked: true
}
CheckBox {
id: multiSelectionCheckBox
text: "Multi selection"
checked: true
}
}
}

View File

@ -36,8 +36,6 @@ SplitView {
NetworkFilter {
id: networkFilter
Layout.preferredWidth: 200
Layout.preferredHeight: 100
Layout.alignment: Qt.AlignHCenter
allNetworks: simulatedNimModel
@ -72,7 +70,6 @@ SplitView {
}
multiSelection: multiSelectionCheckbox.checked
isChainVisible: isChainVisibleCheckbox.checked
}
// Dummy item to make space for popup
@ -229,15 +226,6 @@ SplitView {
checked: false
onCheckedChanged: Qt.callLater(simulatedNimModel.cloneModel, availableNetworks)
}
CheckBox {
id: isChainVisibleCheckbox
Layout.margins: 5
text: "Is chain visible"
checked: true
}
}
}
@ -262,10 +250,10 @@ SplitView {
roles: ["chainId", "layer", "chainName", "isTest", "isEnabled", "iconUrl", "shortName", "chainColor"]
rolesOverride: [{ role: "enabledState", transform: (mD) => {
return simulatedNimModel.areAllEnabled(sourceModel)
? NetworkSelectPopup.UxEnabledState.AllEnabled
? NetworkSelectItemDelegate.UxEnabledState.AllEnabled
: mD.isEnabled
? NetworkSelectPopup.UxEnabledState.Enabled
: NetworkSelectPopup.UxEnabledState.Disabled
? NetworkSelectItemDelegate.UxEnabledState.Enabled
: NetworkSelectItemDelegate.UxEnabledState.Disabled
}
}]
@ -277,11 +265,11 @@ SplitView {
let allEnabled = true
for (let i = 0; i < simulatedNimModel.count; i++) {
const item = simulatedNimModel.get(i)
if(item.enabledState === NetworkSelectPopup.UxEnabledState.Enabled) {
if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
if(item.chainId !== chainId) {
chainIdOnlyEnabled = false
}
} else if(item.enabledState === NetworkSelectPopup.UxEnabledState.Disabled) {
} else if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Disabled) {
if(item.chainId !== chainId) {
chainIdOnlyDisabled = false
}
@ -296,15 +284,15 @@ SplitView {
for (let i = 0; i < simulatedNimModel.count; i++) {
const item = simulatedNimModel.get(i)
if(allEnabled) {
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectPopup.UxEnabledState.Enabled : NetworkSelectPopup.UxEnabledState.Disabled)
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectItemDelegate.UxEnabledState.Enabled : NetworkSelectItemDelegate.UxEnabledState.Disabled)
} else if(chainIdOnlyEnabled || chainIdOnlyDisabled) {
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectPopup.UxEnabledState.AllEnabled)
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectItemDelegate.UxEnabledState.AllEnabled)
} else if(item.chainId === chainId) {
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectPopup.UxEnabledState.Enabled
? NetworkSelectPopup.UxEnabledState.Disabled
:NetworkSelectPopup.UxEnabledState.Enabled)
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled
? NetworkSelectItemDelegate.UxEnabledState.Disabled
:NetworkSelectItemDelegate.UxEnabledState.Enabled)
}
const haveEnabled = item.enabledState !== NetworkSelectPopup.UxEnabledState.Disabled
const haveEnabled = item.enabledState !== NetworkSelectItemDelegate.UxEnabledState.Disabled
if(item.isEnabled !== haveEnabled) {
simulatedNimModel.setProperty(i, "isEnabled", haveEnabled)
}

View File

@ -0,0 +1,138 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import AppLayouts.Chat.panels 1.0
import utils 1.0
import Storybook 1.0
import AppLayouts.Wallet.panels 1.0
import Models 1.0
SplitView {
id: root
Logs { id: logs }
orientation: Qt.Vertical
property bool globalUtilsReady: false
property bool mainModuleReady: false
// globalUtilsInst mock
QtObject {
id: d
Component.onCompleted: {
Utils.globalUtilsInst = this
root.globalUtilsReady = true
}
Component.onDestruction: {
root.globalUtilsReady = false
Utils.globalUtilsInst = {}
}
readonly property string emptyString: ""
property var dummyOverview:({
name: "helloworld",
mixedcaseAddress: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7421",
ens: emptyString,
color: "#2A4AF5",
emoji: "⚽",
balanceLoading: false,
hasBalanceCache: true,
currencyBalance: ({amount: 1.25,
symbol: "USD",
displayDecimals: 4,
stripTrailingZeroes: false}),
isAllAccounts: false,
hideWatchAccounts: false
})
property var dummyAllAccountsOverview:({
name: "helloworld",
mixedcaseAddress: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7421",
ens: emptyString,
color: "#2A4AF5",
emoji: "⚽",
balanceLoading: false,
hasBalanceCache: true,
currencyBalance: ({amount: 1.25,
symbol: "USD",
displayDecimals: 4,
stripTrailingZeroes: false}),
isAllAccounts: true,
hideWatchAccounts: true
})
readonly property QtObject connectionStore: QtObject {
property bool accountBalanceNotAvailable: false
}
readonly property QtObject walletStore: QtObject {
property var allNetworks: enabledNetworks
property var layer1Networks: NetworksModel.layer1Networks
property var layer2Networks: NetworksModel.layer2Networks
property var testNetworks: NetworksModel.testNetworks
property var enabledNetworks: NetworksModel.enabledNetworks
function toggleNetwork(chainId) {
}
function getAllNetworksSupportedString(hovered) {
return hovered ? "<font color=\"" + "#627EEA" + "\">" + "eth:" + "</font>" +
"<font color=\"" + "#E90101" + "\">" + "opt:" + "</font>" +
"<font color=\"" + "#27A0EF" + "\">" + "arb:" + "</font>" : "eth:opt:arb:"
}
}
}
// mainModuleInst mock
QtObject {
function getContactDetailsAsJson(publicKey, getVerificationRequest) {
return JSON.stringify({ ensVerified: false })
}
Component.onCompleted: {
Utils.mainModuleInst = this
root.mainModuleReady = true
}
Component.onDestruction: {
root.mainModuleReady = false
Utils.mainModuleInst = {}
}
}
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
Loader {
anchors.fill: parent
active: globalUtilsReady && mainModuleReady
sourceComponent: WalletHeader {
networkConnectionStore: d.connectionStore
overview: allAccountsCheckbox.checked ? d.dummyAllAccountsOverview : d.dummyOverview
walletStore: d.walletStore
width: parent.width
}
}
}
LogsAndControlsPanel {
id: logsAndControlsPanel
SplitView.minimumHeight: 100
SplitView.preferredHeight: 200
logsView.logText: logs.logText
CheckBox {
id: allAccountsCheckbox
text: "All Accounts"
checked: false
}
}
}

View File

@ -102,6 +102,7 @@ QtObject {
property color black: getColor('black')
property color white: getColor('white')
property color transparent: "#00000000"
property color dropShadow: getColor('black', 0.12)
property color dropShadow2

View File

@ -295,7 +295,6 @@ StatusScrollView {
testNetworks: root.testNetworks
enabledNetworks: root.enabledNetworks
isChainVisible: false
multiSelection: false
onToggleNetwork: (network) =>

View File

@ -58,6 +58,7 @@ Item {
contactsStore: root.contactsStore
sendModal: root.sendModalPopup
networkConnectionStore: root.networkConnectionStore
onLaunchShareAddressModal: Global.openPopup(receiveModalComponent);
}
}
@ -119,6 +120,14 @@ Item {
width: parent.width
walletStore: RootStore
networkConnectionStore: root.networkConnectionStore
onLaunchShareAddressModal: Global.openPopup(receiveModalComponent)
}
}
Component {
id: receiveModalComponent
ReceiveModal {
anchors.centerIn: parent
}
}
}

View File

@ -1,30 +1,24 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import shared 1.0
import shared.panels 1.0
import shared.controls 1.0
import utils 1.0
import "../popups"
import "../views"
Item {
StatusComboBox {
id: root
implicitWidth: 130
implicitHeight: parent.height
required property var allNetworks
required property var layer1Networks
required property var layer2Networks
required property var testNetworks
required property var enabledNetworks
property bool isChainVisible: true
property bool multiSelection: true
/// \c network is a network.model.nim entry
@ -37,6 +31,7 @@ Item {
property string selectedChainName: ""
property string selectedIconUrl: ""
property bool allSelected: root.enabledNetworks.count === root.allNetworks.count
// Persist selection between selectPopupLoader reloads
property var currentModel: layer1Networks
@ -51,103 +46,88 @@ Item {
}
}
Item {
id: selectRectangleItem
control.padding: 12
control.spacing: 0
control.rightPadding: 36
control.topPadding: 7
control.popup.width: 430
width: parent.width
height: 56
size: StatusComboBox.Size.Small
// FIXME this should be a (styled) ComboBox
StatusListItem {
implicitWidth: parent.width
implicitHeight: 40
anchors.verticalCenter: parent.verticalCenter
border.width: 1
border.color: Theme.palette.directColor7
color: "transparent"
objectName: "networkSelectorButton"
leftPadding: 12
rightPadding: 12
statusListItemTitle.font.pixelSize: 13
statusListItemTitle.font.weight: Font.Medium
statusListItemTitle.color: Theme.palette.baseColor1
title: root.multiSelection
? (root.enabledNetworks.count === root.allNetworks.count
? qsTr("All networks")
: qsTr("%n network(s)", "", root.enabledNetworks.count))
: d.selectedChainName
control.background: Rectangle {
height: 38
radius: 8
color: root.control.hovered ? Theme.palette.baseColor2 : "transparent"
border.color: Theme.palette.directColor7
}
contentItem: RowLayout {
spacing: 16
StatusSmartIdenticon {
Layout.alignment: Qt.AlignVCenter
asset.height: 24
asset.width: asset.height
asset.width: 24
asset.isImage: !root.multiSelection
asset.name: !root.multiSelection ? Style.svg(d.selectedIconUrl) : ""
components:[
StatusIcon {
width: 16
height: 16
icon: "chevron-down"
color: Theme.palette.baseColor1
active: !root.multiSelection
visible: active
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
font.pixelSize: 13
font.weight: Font.Medium
elide: Text.ElideRight
lineHeight: 24
lineHeightMode: Text.FixedHeight
verticalAlignment: Text.AlignVCenter
text: root.multiSelection ? (d.allSelected ? qsTr("All networks") : "") : d.selectedChainName
color: Theme.palette.baseColor1
visible: !!text
}
Row {
spacing: -4
visible: !d.allSelected && chainRepeater.count > 0
Repeater {
id: chainRepeater
model: root.enabledNetworks
delegate: StatusRoundedImage {
width: 24
height: 24
visible: image.source !== ""
border.width: index === 0 ? 0 : 1
border.color: Theme.palette.white
image.source: Style.svg("tiny/" + model.iconUrl)
z: index + 1
}
]
onClicked: {
selectPopupLoader.active = !selectPopupLoader.active
}
}
}
Row {
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.halfPadding
spacing: Style.current.smallPadding
visible: root.isChainVisible && chainRepeater.count > 0
control.popup.contentItem: NetworkSelectionView {
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
Repeater {
id: chainRepeater
model: root.enabledNetworks
delegate: InformationTag {
tagPrimaryLabel.text: model.shortName
tagPrimaryLabel.color: model.chainColor
image.source: Style.svg("tiny/" + model.iconUrl)
}
}
}
implicitWidth: contentWidth
implicitHeight: contentHeight
Loader {
id: selectPopupLoader
active: false
sourceComponent: NetworkSelectPopup {
id: selectPopup
x: -width + selectRectangleItem.width + 5
y: selectRectangleItem.height + 5
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
singleSelection {
enabled: !root.multiSelection
currentModel: d.currentModel
currentIndex: d.currentIndex
}
useEnabledRole: false
onToggleNetwork: (network, networkModel, index) => {
d.selectedChainName = network.chainName
d.selectedIconUrl = network.iconUrl
d.currentModel = networkModel
d.currentIndex = index
root.toggleNetwork(network)
}
onClosed: selectPopupLoader.active = false
singleSelection {
enabled: !root.multiSelection
currentModel: d.currentModel
currentIndex: d.currentIndex
}
onLoaded: item.open()
useEnabledRole: false
onToggleNetwork: (network, networkModel, index) => {
d.selectedChainName = network.chainName
d.selectedIconUrl = network.iconUrl
d.currentModel = networkModel
d.currentIndex = index
root.toggleNetwork(network)
if(singleSelection.enabled)
control.popup.close()
}
}
}

View File

@ -0,0 +1,97 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import utils 1.0
import "../stores/NetworkSelectPopup"
StatusListItem {
id: root
property var networkModel: null
property var singleSelection
property var radioButtonGroup
property bool useEnabledRole: true
signal toggleNetwork(var network, var model, int index)
/// Mirrors Nim's UxEnabledState enum from networks/item.nim
enum UxEnabledState {
Enabled,
AllEnabled,
Disabled
}
QtObject {
id: d
property SingleSelectionInfo tmpObject: SingleSelectionInfo { enabled: true }
}
objectName: model.chainName
title: model.chainName
asset.height: 24
asset.width: 24
asset.isImage: true
asset.name: Style.svg(model.iconUrl)
onClicked: {
if(!root.singleSelection.enabled) {
checkBox.nextCheckState()
} else if(!radioButton.checked) { // Don't allow uncheck
radioButton.toggle()
}
}
components: [
StatusCheckBox {
id: checkBox
tristate: true
visible: !root.singleSelection.enabled
checkState: {
if(root.useEnabledRole) {
return model.isEnabled ? Qt.Checked : Qt.Unchecked
} else if(model.enabledState === NetworkSelectItemDelegate.Enabled) {
return Qt.Checked
} else {
if( model.enabledState === NetworkSelectItemDelegate.AllEnabled) {
return Qt.PartiallyChecked
} else {
return Qt.Unchecked
}
}
}
nextCheckState: () => {
Qt.callLater(root.toggleNetwork, model, root.networkModel, model.index)
return Qt.PartiallyChecked
}
},
StatusRadioButton {
id: radioButton
visible: root.singleSelection.enabled
size: StatusRadioButton.Size.Large
ButtonGroup.group: root.radioButtonGroup
checked: root.singleSelection.currentModel === root.networkModel && root.singleSelection.currentIndex === model.index
property SingleSelectionInfo exchangeObject: null
function setNewInfo(networkModel, index) {
d.tmpObject.currentModel = networkModel
d.tmpObject.currentIndex = index
exchangeObject = d.tmpObject
d.tmpObject = root.singleSelection
root.singleSelection = exchangeObject
exchangeObject = null
}
onCheckedChanged: {
if(checked && (root.singleSelection.currentModel !== root.networkModel || root.singleSelection.currentIndex !== model.index)) {
setNewInfo(root.networkModel, model.index)
root.toggleNetwork(({chainId: model.chainId, chainName: model.chainName, iconUrl: model.iconUrl}), root.networkModel, model.index)
}
}
}
]
}

View File

@ -1 +1,2 @@
NetworkFilter 1.0 NetworkFilter.qml
NetworkSelectItemDelegate 1.0 NetworkSelectItemDelegate.qml

View File

@ -9,16 +9,18 @@ import StatusQ.Core.Theme 0.1
import utils 1.0
import shared.controls 1.0
import "../popups"
import "../controls"
import "../popups"
Rectangle {
id: walletFooter
id: root
property var sendModal
property var walletStore
property var networkConnectionStore
signal launchShareAddressModal()
height: 61
color: Theme.palette.statusAppLayout.rightPanelBackgroundColor
@ -48,7 +50,7 @@ Rectangle {
icon.name: "receive"
text: qsTr("Receive")
onClicked: function () {
Global.openPopup(receiveModalComponent);
launchShareAddressModal()
}
}
@ -74,13 +76,6 @@ Rectangle {
}
}
Component {
id: receiveModalComponent
ReceiveModal {
anchors.centerIn: parent
}
}
Component {
id: buySellModal
CryptoServicesModal {}

View File

@ -1,17 +1,14 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import utils 1.0
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import "../controls"
import "../stores"
@ -23,60 +20,135 @@ Item {
property var store
property var walletStore
signal launchShareAddressModal()
signal switchHideWatchOnlyAccounts()
implicitHeight: 88
GridLayout {
width: parent.width
columns: 2
rowSpacing: 0
// account + balance
RowLayout {
Layout.preferredHeight: 56
spacing: Style.current.halfPadding
StatusBaseText {
objectName: "accountName"
Layout.alignment: Qt.AlignVCenter
verticalAlignment: Text.AlignVCenter
color: overview.isAllAccounts ? Theme.palette.directColor5 : overview.color
lineHeightMode: Text.FixedHeight
lineHeight: 38
font.bold: true
font.pixelSize: 28
text: overview.isAllAccounts ? qsTr("All Accounts") : overview.name
}
StatusEmoji {
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: 28
Layout.preferredHeight: 28
emojiId: StatusQUtils.Emoji.iconId(overview.emoji ?? "", StatusQUtils.Emoji.size.big) || ""
visible: !overview.isAllAccounts
}
}
RowLayout {
spacing: 16
Layout.alignment: Qt.AlignTrailing
Layout.topMargin: 5
StatusButton {
Layout.preferredHeight: 38
Layout.alignment: Qt.AlignTop
spacing: 8
size: StatusBaseButton.Size.Small
borderColor: Theme.palette.directColor7
normalColor: Theme.palette.transparent
hoverColor: Theme.palette.baseColor2
font.weight: Font.Normal
textAlignment: Qt.AlignTop | Qt.AlignHCenter
textPosition: StatusBaseButton.TextPosition.Left
textColor: Theme.palette.baseColor1
text: overview.ens || StatusQUtils.Utils.elideText(overview.mixedcaseAddress, 6, 4)
icon.name: "invite-users"
icon.height: 16
icon.width: 16
icon.color: hovered ? Theme.palette.directColor1 : Theme.palette.baseColor1
onClicked: launchShareAddressModal()
visible: !overview.isAllAccounts
}
StatusButton {
Layout.preferredHeight: 38
Layout.alignment: Qt.AlignTop
spacing: 8
size: StatusBaseButton.Size.Small
borderColor: Theme.palette.directColor7
normalColor: Theme.palette.transparent
hoverColor: Theme.palette.baseColor2
font.weight: Font.Normal
textAlignment: Qt.AlignTop | Qt.AlignHCenter
textColor: Theme.palette.baseColor1
text: overview.hideWatchAccounts ? qsTr("Show watch-only"): qsTr("Hide watch-only")
icon.name: overview.hideWatchAccounts ? "show" : "hide"
icon.height: 16
icon.width: 16
icon.color: Theme.palette.baseColor1
// To-do once all accounts view is implemented, filter watch only accounts
onClicked: switchHideWatchOnlyAccounts()
visible: overview.isAllAccounts
}
// network filter
NetworkFilter {
id: networkFilter
Layout.alignment: Qt.AlignTop
allNetworks: walletStore.allNetworks
layer1Networks: walletStore.layer1Networks
layer2Networks: walletStore.layer2Networks
testNetworks: walletStore.testNetworks
enabledNetworks: walletStore.enabledNetworks
onToggleNetwork: (network) => {
walletStore.toggleNetwork(network.chainId)
}
}
}
RowLayout {
spacing: 4
visible: !networkConnectionStore.accountBalanceNotAvailable
StatusTextWithLoadingState {
font.pixelSize: 28
font.bold: true
text: overview.name
customColor: Theme.palette.directColor1
text: loading ? Constants.dummyText : LocaleUtils.currencyAmountToLocaleString(root.overview.currencyBalance, {noSymbol: true})
loading: root.overview.balanceLoading
lineHeightMode: Text.FixedHeight
lineHeight: 38
}
StatusTextWithLoadingState {
Layout.alignment: Qt.AlignVCenter
font.pixelSize: 28
Layout.alignment: Qt.AlignBottom
font.pixelSize: 15
font.bold: true
customColor: Theme.palette.baseColor1
text: loading ? Constants.dummyText : LocaleUtils.currencyAmountToLocaleString(root.overview.currencyBalance)
customColor: Theme.palette.directColor1
text: loading ? Constants.dummyText : root.overview.currencyBalance.symbol
loading: root.overview.balanceLoading
visible: !networkConnectionStore.accountBalanceNotAvailable
lineHeightMode: Text.FixedHeight
lineHeight: 25
}
}
// network filter
NetworkFilter {
id: networkFilter
Layout.alignment: Qt.AlignTrailing
Layout.rowSpan: 2
allNetworks: walletStore.allNetworks
layer1Networks: walletStore.layer1Networks
layer2Networks: walletStore.layer2Networks
testNetworks: walletStore.testNetworks
enabledNetworks: walletStore.enabledNetworks
onToggleNetwork: (network) => {
walletStore.toggleNetwork(network.chainId)
}
}
StatusAddressPanel {
objectName: "addressPanel"
value: overview.ens || overview.mixedcaseAddress
ens: !!overview.ens
autHideCopyIcon: true
expanded: false
onDoCopy: () => root.store.copyToClipboard(overview.mixedcaseAddress)
}
}
}

View File

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

View File

@ -1,19 +1,15 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups.Dialog 0.1
import utils 1.0
import SortFilterProxyModel 0.2
import "./NetworkSelectPopup"
import "../stores/NetworkSelectPopup"
import "../controls"
import "../views"
StatusDialog {
id: root
@ -45,27 +41,18 @@ StatusDialog {
/// \see SingleSelectionInfo
signal toggleNetwork(var network, var model, int index)
/// Mirrors Nim's UxEnabledState enum from networks/item.nim
enum UxEnabledState {
Enabled,
AllEnabled,
Disabled
}
QtObject {
id: d
property SingleSelectionInfo singleSelection: SingleSelectionInfo {}
property SingleSelectionInfo tmpObject: SingleSelectionInfo { enabled: true }
}
background: Rectangle {
radius: Style.current.radius
color: Style.current.background
border.color: Style.current.border
layer.enabled: true
layer.effect: DropShadow{
layer.effect: DropShadow {
verticalOffset: 3
radius: 8
samples: 15
@ -75,142 +62,19 @@ StatusDialog {
}
}
contentItem: StatusScrollView {
contentItem: NetworkSelectionView {
id: scrollView
width: root.width
height: root.height
contentHeight: content.height
contentWidth: availableWidth
padding: 0
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column {
id: content
width: childrenRect.width
spacing: 4
Repeater {
id: chainRepeater1
width: parent.width
height: parent.height
objectName: "networkSelectPopupChainRepeaterLayer1"
model: root.layer1Networks
delegate: ChainItemDelegate {
networkModel: chainRepeater1.model
}
}
StatusBaseText {
font.pixelSize: Style.current.primaryTextFontSize
color: Theme.palette.baseColor1
text: qsTr("Layer 2")
height: 40
leftPadding: 16
topPadding: 10
verticalAlignment: Text.AlignVCenter
visible: chainRepeater2.count > 0
}
Repeater {
id: chainRepeater2
model: root.layer2Networks
delegate: ChainItemDelegate {
networkModel: chainRepeater2.model
}
}
Repeater {
id: chainRepeater3
model: root.testNetworks
delegate: ChainItemDelegate {
networkModel: chainRepeater3.model
}
}
layer1Networks: root.layer1Networks
layer2Networks: root.layer2Networks
testNetworks: root.testNetworks
useEnabledRole: root.useEnabledRole
singleSelection: d.singleSelection
onToggleNetwork: {
root.toggleNetwork(network, model, index)
if(d.singleSelection.enabled)
close()
}
}
component ChainItemDelegate: StatusListItem {
id: chainItemDelegate
property var networkModel: null
objectName: model.chainName
implicitHeight: 48
implicitWidth: scrollView.width
title: model.chainName
asset.height: 24
asset.width: 24
asset.isImage: true
asset.name: Style.svg(model.iconUrl)
onClicked: {
if(!d.singleSelection.enabled) {
checkBox.nextCheckState()
} else if(!radioButton.checked) { // Don't allow uncheck
radioButton.toggle()
}
}
components: [
StatusCheckBox {
id: checkBox
tristate: true
visible: !d.singleSelection.enabled
checkState: {
if(root.useEnabledRole) {
return model.isEnabled ? Qt.Checked : Qt.Unchecked
} else if(model.enabledState === NetworkSelectPopup.Enabled) {
return Qt.Checked
} else {
if( model.enabledState === NetworkSelectPopup.AllEnabled) {
return Qt.PartiallyChecked
} else {
return Qt.Unchecked
}
}
}
nextCheckState: () => {
Qt.callLater(root.toggleNetwork, model, chainItemDelegate.networkModel, model.index)
return Qt.PartiallyChecked
}
},
StatusRadioButton {
id: radioButton
visible: d.singleSelection.enabled
size: StatusRadioButton.Size.Large
ButtonGroup.group: radioBtnGroup
checked: d.singleSelection.currentModel === chainItemDelegate.networkModel && d.singleSelection.currentIndex === model.index
property SingleSelectionInfo exchangeObject: null
function setNewInfo(networkModel, index) {
d.tmpObject.currentModel = networkModel
d.tmpObject.currentIndex = index
exchangeObject = d.tmpObject
d.tmpObject = d.singleSelection
d.singleSelection = exchangeObject
exchangeObject = null
}
onCheckedChanged: {
if(checked && (d.singleSelection.currentModel !== chainItemDelegate.networkModel || d.singleSelection.currentIndex !== model.index)) {
setNewInfo(chainItemDelegate.networkModel, model.index)
root.toggleNetwork(model, chainItemDelegate.networkModel, model.index)
close()
}
}
}
]
}
ButtonGroup {
id: radioBtnGroup
}
}

View File

@ -0,0 +1,99 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import "../stores/NetworkSelectPopup"
import "../controls"
StatusScrollView {
id: root
property var testNetworks: null
required property var layer1Networks
required property var layer2Networks
property bool useEnabledRole: true
property SingleSelectionInfo singleSelection: SingleSelectionInfo {}
signal toggleNetwork(var network, var model, int index)
contentHeight: content.height
contentWidth: availableWidth
padding: 0
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column {
id: content
width: childrenRect.width
spacing: 4
Repeater {
id: chainRepeater1
width: parent.width
height: parent.height
objectName: "networkSelectPopupChainRepeaterLayer1"
model: root.layer1Networks
delegate: NetworkSelectItemDelegate {
implicitHeight: 48
implicitWidth: root.width
radioButtonGroup: radioBtnGroup
networkModel: chainRepeater1.model
useEnabledRole: root.useEnabledRole
singleSelection: root.singleSelection
onToggleNetwork: root.toggleNetwork(network, model, index)
}
}
StatusBaseText {
font.pixelSize: Style.current.primaryTextFontSize
color: Theme.palette.baseColor1
text: qsTr("Layer 2")
height: 40
leftPadding: 16
topPadding: 10
verticalAlignment: Text.AlignVCenter
visible: chainRepeater2.count > 0
}
Repeater {
id: chainRepeater2
model: root.layer2Networks
delegate: NetworkSelectItemDelegate {
implicitHeight: 48
implicitWidth: root.width
radioButtonGroup: radioBtnGroup
networkModel: chainRepeater2.model
useEnabledRole: root.useEnabledRole
singleSelection: root.singleSelection
onToggleNetwork: root.toggleNetwork(network, model, index)
}
}
Repeater {
id: chainRepeater3
model: root.testNetworks
delegate: NetworkSelectItemDelegate {
implicitHeight: 48
implicitWidth: root.width
radioButtonGroup: radioBtnGroup
networkModel: chainRepeater3.model
useEnabledRole: root.useEnabledRole
singleSelection: root.singleSelection
onToggleNetwork: root.toggleNetwork(network, model, index)
}
}
}
ButtonGroup {
id: radioBtnGroup
}
}

View File

@ -22,6 +22,8 @@ Item {
property var sendModal
property var networkConnectionStore
signal launchShareAddressModal()
function resetStack() {
stack.currentIndex = 0;
}
@ -50,12 +52,14 @@ Item {
}
ColumnLayout {
spacing: 0
WalletHeader {
Layout.fillWidth: true
overview: RootStore.overview
store: root.store
walletStore: RootStore
networkConnectionStore: root.networkConnectionStore
onLaunchShareAddressModal: root.launchShareAddressModal()
}
StatusTabBar {
id: walletTabBar
@ -123,7 +127,7 @@ Item {
visible: (stack.currentIndex === 2)
assetsLoading: RootStore.assetsLoading
address: RootStore.overview.mixedcaseAddress
address: RootStore.overview.mixedcaseAddress
networkConnectionStore: root.networkConnectionStore
}

View File

@ -151,7 +151,7 @@ StatusDialog {
anchors.topMargin: -height - 18
model: popup.store.senderAccounts
selectedAccount: !!popup.selectedAccount ? popup.selectedAccount: {}
chainShortNames: store.getAllNetworksSupportedString()
chainShortNames: store.getAllNetworksSupportedPrefix()
onSelectedIndexChanged: store.switchSenderAccount(selectedIndex)
}

View File

@ -294,13 +294,8 @@ QtObject {
return walletSectionTransactions.getTransactions()
}
function getAllNetworksSupportedString() {
let result = ""
for(var i = 0; i < allNetworks.count; i++) {
let shortName = allNetworks.rowData(i, "shortName")
result += shortName + ':'
}
return result
function getAllNetworksSupportedPrefix() {
return networksModule.getAllNetworksSupportedPrefix()
}
function switchSenderAccount(index) {

View File

@ -138,7 +138,7 @@ Loader {
id: myAccountRecipient
WalletAccountListItem {
implicitWidth: parent.width
chainShortNames: store.getAllNetworksSupportedString()
chainShortNames: store.getAllNetworksSupportedPrefix()
modelData: root.selectedRecipient
radius: 8
clearVisible: true

View File

@ -138,7 +138,7 @@ Item {
delegate: WalletAccountListItem {
implicitWidth: ListView.view.width
modelData: model
chainShortNames: root.store.getAllNetworksSupportedString()
chainShortNames: root.store.getAllNetworksSupportedPrefix()
onClicked: recipientSelected({name: modelData.name,
address: modelData.address,
color: modelData.color,