refactoring(NetworkSelectItemDelegate): Remove backend dependency and clean the API

This is the first step in refactoring the NetworkFilter, by cleaning the base component that handles the check states.
This component supports multiple configurations:
1. Single selection with or without radio button
2. Multiple selection with or without checkbox
3. Automatic handling of the check state. The component will change the check state based on user clicks
4. Manual handling of the check state. The component will not change the check state, but offers a toggled signal and expects the user to change the check state based on external flows

+ Fix minor bugs
This commit is contained in:
Alex Jbanca 2024-06-12 11:52:11 +03:00 committed by Alex Jbanca
parent 5bdda2e6d9
commit 429203cd66
12 changed files with 566 additions and 110 deletions

View File

@ -54,6 +54,8 @@ SplitView {
sourceModel: NetworksModel.flatNetworks
filters: ValueFilter { roleName: "isTest"; value: areTestNetworksEnabledCheckbox.checked }
}
property var filteredFlatModel: networks
property bool areTestNetworksEnabled: areTestNetworksEnabledCheckbox.checked
function toggleNetwork(chainId) {
}
@ -72,6 +74,13 @@ SplitView {
function processPreferredSharingNetworkToggle(preferredSharingNetworksArray, network) {
console.warn("processPreferredSharingNetworkToggle :: preferredSharingNetworksArray ::", preferredSharingNetworksArray, "network :: ", network)
const chainId = network.chainId.toString()
if (preferredSharingNetworksArray.includes(chainId)) {
preferredSharingNetworksArray.splice(preferredSharingNetworksArray.indexOf(chainId), 1)
} else {
preferredSharingNetworksArray.push(chainId)
}
return [...preferredSharingNetworksArray]
}
}

View File

@ -9,6 +9,7 @@ import SortFilterProxyModel 0.2
import AppLayouts.stores 1.0
import AppLayouts.Wallet.controls 1.0
import AppLayouts.Wallet.views 1.0
SplitView {
id: root
@ -32,10 +33,10 @@ SplitView {
roles: ["chainId", "layer", "chainName", "isTest", "isEnabled", "iconUrl", "shortName", "chainColor"]
rolesOverride: [{ role: "enabledState", transform: (mD) => {
return simulatedNimModel.areAllEnabled(sourceModel)
? NetworkSelectItemDelegate.UxEnabledState.AllEnabled
? NetworkSelectionView.UxEnabledState.AllEnabled
: mD.isEnabled
? NetworkSelectItemDelegate.UxEnabledState.Enabled
: NetworkSelectItemDelegate.UxEnabledState.Disabled
? NetworkSelectionView.UxEnabledState.Enabled
: NetworkSelectionView.UxEnabledState.Disabled
}
}]
@ -47,11 +48,11 @@ SplitView {
let allEnabled = true
for (let i = 0; i < simulatedNimModel.count; i++) {
const item = simulatedNimModel.get(i)
if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
if(item.enabledState === NetworkSelectionView.UxEnabledState.Enabled) {
if(item.chainId !== chainId) {
chainIdOnlyEnabled = false
}
} else if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Disabled) {
} else if(item.enabledState === NetworkSelectionView.UxEnabledState.Disabled) {
if(item.chainId !== chainId) {
chainIdOnlyDisabled = false
}
@ -66,15 +67,15 @@ SplitView {
for (let i = 0; i < simulatedNimModel.count; i++) {
const item = simulatedNimModel.get(i)
if(allEnabled) {
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectItemDelegate.UxEnabledState.Enabled : NetworkSelectItemDelegate.UxEnabledState.Disabled)
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectionView.UxEnabledState.Enabled : NetworkSelectionView.UxEnabledState.Disabled)
} else if(chainIdOnlyEnabled || chainIdOnlyDisabled) {
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectItemDelegate.UxEnabledState.AllEnabled)
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectionView.UxEnabledState.AllEnabled)
} else if(item.chainId === chainId) {
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled
? NetworkSelectItemDelegate.UxEnabledState.Disabled
: NetworkSelectItemDelegate.UxEnabledState.Enabled)
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectionView.UxEnabledState.Enabled
? NetworkSelectionView.UxEnabledState.Disabled
: NetworkSelectionView.UxEnabledState.Enabled)
}
const haveEnabled = item.enabledState !== NetworkSelectItemDelegate.UxEnabledState.Disabled
const haveEnabled = item.enabledState !== NetworkSelectionView.UxEnabledState.Disabled
if(item.isEnabled !== haveEnabled) {
simulatedNimModel.setProperty(i, "isEnabled", haveEnabled)
}

View File

@ -0,0 +1,97 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQml 2.15
import StatusQ.Core 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import AppLayouts.Wallet.controls 1.0
import Models 1.0
import Storybook 1.0
import SortFilterProxyModel 0.2
import utils 1.0
SplitView {
id: root
Item {
implicitWidth: delegate.width
NetworkSelectItemDelegate {
id: delegate
title: "Ethereum"
iconUrl: Style.svg("network/Network=Ethereum")
showIndicator: true
multiSelection: true
checkState: checkStateSelector.checkState
nextCheckState: checkState === Qt.Unchecked ? Qt.PartiallyChecked :
checkState === Qt.PartiallyChecked ? Qt.Checked : Qt.Unchecked
onCheckStateChanged: {
checkStateSelector.checkState = checkState
}
}
}
Pane {
id: pane
SplitView.fillWidth: true
ColumnLayout {
CheckBox {
text: "showIndicator"
checked: delegate.showIndicator
onCheckedChanged: {
delegate.showIndicator = checked
}
}
CheckBox {
text: "multiSelection"
checked: delegate.multiSelection
onCheckedChanged: {
delegate.multiSelection = checked
}
}
Label {
text: "title"
}
TextField {
text: delegate.title
onTextChanged: {
delegate.title = text
}
}
Label {
text: "iconUrl"
}
TextField {
text: delegate.iconUrl
onTextChanged: {
delegate.iconUrl = text
}
}
CheckBox {
id: checkStateSelector
text: "checkedState"
tristate: true
checked: true
onCheckStateChanged: {
if(delegate.checkState !== checkState) {
delegate.checkState = checkState
}
}
}
}
}
}
// category: Controls

View File

@ -10,6 +10,7 @@ import utils 1.0
import AppLayouts.Wallet.popups 1.0
import AppLayouts.Wallet.controls 1.0
import AppLayouts.Wallet.views 1.0
import AppLayouts.stores 1.0
import Models 1.0
@ -219,10 +220,10 @@ SplitView {
roles: ["chainId", "layer", "chainName", "isTest", "isEnabled", "iconUrl", "shortName", "chainColor"]
rolesOverride: [{ role: "enabledState", transform: (mD) => {
return simulatedNimModel.areAllEnabled(sourceModel)
? NetworkSelectItemDelegate.UxEnabledState.AllEnabled
? NetworkSelectionView.UxEnabledState.AllEnabled
: mD.isEnabled
? NetworkSelectItemDelegate.UxEnabledState.Enabled
: NetworkSelectItemDelegate.UxEnabledState.Disabled
? NetworkSelectionView.UxEnabledState.Enabled
: NetworkSelectionView.UxEnabledState.Disabled
}
}]
@ -234,11 +235,11 @@ SplitView {
let allEnabled = true
for (let i = 0; i < simulatedNimModel.count; i++) {
const item = simulatedNimModel.get(i)
if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
if(item.enabledState === NetworkSelectionView.UxEnabledState.Enabled) {
if(item.chainId !== chainId) {
chainIdOnlyEnabled = false
}
} else if(item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Disabled) {
} else if(item.enabledState === NetworkSelectionView.UxEnabledState.Disabled) {
if(item.chainId !== chainId) {
chainIdOnlyDisabled = false
}
@ -253,15 +254,15 @@ SplitView {
for (let i = 0; i < simulatedNimModel.count; i++) {
const item = simulatedNimModel.get(i)
if(allEnabled) {
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectItemDelegate.UxEnabledState.Enabled : NetworkSelectItemDelegate.UxEnabledState.Disabled)
simulatedNimModel.setProperty(i, "enabledState", item.chainId === chainId ? NetworkSelectionView.UxEnabledState.Enabled : NetworkSelectionView.UxEnabledState.Disabled)
} else if(chainIdOnlyEnabled || chainIdOnlyDisabled) {
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectItemDelegate.UxEnabledState.AllEnabled)
simulatedNimModel.setProperty(i, "enabledState", NetworkSelectionView.UxEnabledState.AllEnabled)
} else if(item.chainId === chainId) {
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled
? NetworkSelectItemDelegate.UxEnabledState.Disabled
:NetworkSelectItemDelegate.UxEnabledState.Enabled)
simulatedNimModel.setProperty(i, "enabledState", item.enabledState === NetworkSelectionView.UxEnabledState.Enabled
? NetworkSelectionView.UxEnabledState.Disabled
:NetworkSelectionView.UxEnabledState.Enabled)
}
const haveEnabled = item.enabledState !== NetworkSelectItemDelegate.UxEnabledState.Disabled
const haveEnabled = item.enabledState !== NetworkSelectionView.UxEnabledState.Disabled
if(item.isEnabled !== haveEnabled) {
simulatedNimModel.setProperty(i, "isEnabled", haveEnabled)
}

View File

@ -0,0 +1,260 @@
import QtQuick 2.15
import QtTest 1.15
import AppLayouts.Wallet.controls 1.0
import utils 1.0
Item {
id: root
width: 600
height: 400
Component {
id: componentUnderTest
NetworkSelectItemDelegate {
anchors.centerIn: parent
title: "Ethereum"
iconUrl: Style.svg("network/Network=Ethereum")
onToggled: root.onToggledHandler()
}
}
SignalSpy {
id: toggledSpy
target: controlUnderTest
signalName: "toggled"
}
SignalSpy {
id: checkStateChangedSpy
target: controlUnderTest
signalName: "checkStateChanged"
}
property NetworkSelectItemDelegate controlUnderTest: null
property var onToggledHandler: function(){}
property int externalCheckState: Qt.Unchecked
TestCase {
name: "NetworkSelectItemDelegate"
when: windowShown
function init() {
controlUnderTest = createTemporaryObject(componentUnderTest, root)
toggledSpy.clear()
checkStateChangedSpy.clear()
onToggledHandler = function() {}
}
function test_basicGeometry() {
verify(!!controlUnderTest)
verify(controlUnderTest.width > 0)
verify(controlUnderTest.height > 0)
}
function test_title() {
verify(!!controlUnderTest)
compare(controlUnderTest.title, "Ethereum")
controlUnderTest.title = "Polygon"
compare(controlUnderTest.title, "Polygon")
controlUnderTest.title = ""
compare(controlUnderTest.title, "")
controlUnderTest.title = "Ethereum"
}
function test_icon() {
verify(!!controlUnderTest)
compare(controlUnderTest.iconUrl, Style.svg("network/Network=Ethereum"))
compare(findChild(controlUnderTest, "statusRoundImage").image.source, Style.svg("network/Network=Ethereum"))
controlUnderTest.iconUrl = Style.svg("network/Network=Polygon")
compare(controlUnderTest.iconUrl, Style.svg("network/Network=Polygon"))
compare(findChild(controlUnderTest, "statusRoundImage").image.source, Style.svg("network/Network=Polygon"))
}
function test_indicatorConfig() {
verify(!!controlUnderTest)
verify(!!findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum"))
verify(!findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum"))
compare(controlUnderTest.showIndicator, true)
compare(controlUnderTest.multiSelection, false)
//changing to multiselect -> indicator switches to checkbox
controlUnderTest.multiSelection = true
waitForRendering(controlUnderTest)
waitForItemPolished(controlUnderTest)
verify(!!findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum"))
verify(!findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum"))
//changing removing indicator
controlUnderTest.showIndicator = false
waitForRendering(controlUnderTest)
waitForItemPolished(controlUnderTest)
verify(!findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum"))
verify(!findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum"))
}
function test_toggleByClick() {
verify(!!controlUnderTest)
mouseClick(controlUnderTest)
tryCompare(toggledSpy, "count", 1)
const image = findChild(controlUnderTest, "statusRoundImage")
mouseClick(image)
tryCompare(toggledSpy, "count", 2)
const radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
mouseClick(radioButton)
tryCompare(toggledSpy, "count", 3)
controlUnderTest.multiSelection = true
waitForItemPolished(controlUnderTest)
const checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
mouseClick(checkBox)
tryCompare(toggledSpy, "count", 4)
}
function test_autoCheckStateChanges() {
verify(!!controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Checked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
const radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
mouseClick(radioButton)
compare(controlUnderTest.checkState, Qt.Checked)
mouseClick(radioButton)
compare(controlUnderTest.checkState, Qt.Unchecked)
controlUnderTest.multiSelection = true
waitForItemPolished(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
const checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
mouseClick(checkBox)
waitForItemPolished(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Checked)
mouseClick(checkBox)
compare(controlUnderTest.checkState, Qt.Unchecked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Checked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
}
function test_manualCheckStateChanges() {
verify(!!controlUnderTest)
// checkState is not bound to nextCheckState => no automatic check changes
controlUnderTest.nextCheckState = Qt.binding(() => controlUnderTest.checkState)
compare(controlUnderTest.checkState, Qt.Unchecked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
let radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
mouseClick(radioButton)
compare(controlUnderTest.checkState, Qt.Unchecked)
controlUnderTest.multiSelection = true
waitForItemPolished(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
let checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
mouseClick(checkBox)
compare(controlUnderTest.checkState, Qt.Unchecked)
controlUnderTest.multiSelection = false
waitForItemPolished(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
root.onToggledHandler = function() {
controlUnderTest.checkState = controlUnderTest.checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
}
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Checked)
radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
mouseClick(radioButton)
compare(controlUnderTest.checkState, Qt.Unchecked)
controlUnderTest.multiSelection = true
root.onToggledHandler = function() {
controlUnderTest.checkState = controlUnderTest.checkState === Qt.Unchecked ? Qt.PartiallyChecked :
controlUnderTest.checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
}
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.PartiallyChecked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Checked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
mouseClick(checkBox)
compare(controlUnderTest.checkState, Qt.PartiallyChecked)
mouseClick(checkBox)
compare(controlUnderTest.checkState, Qt.Checked)
mouseClick(checkBox)
compare(controlUnderTest.checkState, Qt.Unchecked)
}
function test_checkStateBindings() {
verify(!!controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
compare(root.externalCheckState, Qt.Unchecked)
controlUnderTest.checkState = Qt.binding(() => root.externalCheckState)
compare(controlUnderTest.checkState, root.externalCheckState)
tryCompare(checkStateChangedSpy, "count", 0)
root.externalCheckState = Qt.Checked
compare(controlUnderTest.checkState, Qt.Checked)
tryCompare(checkStateChangedSpy, "count", 1)
root.externalCheckState = Qt.Unchecked
compare(controlUnderTest.checkState, Qt.Unchecked)
tryCompare(checkStateChangedSpy, "count", 2)
}
function test_interactiveConfig() {
verify(!!controlUnderTest)
compare(controlUnderTest.interactive, true)
controlUnderTest.interactive = false
compare(controlUnderTest.checkState, Qt.Unchecked)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
let radioButton = findChild(controlUnderTest, "networkSelectionRadioButton_Ethereum")
mouseClick(radioButton)
compare(controlUnderTest.checkState, Qt.Unchecked)
controlUnderTest.multiSelection = true
waitForItemPolished(controlUnderTest)
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
let checkBox = findChild(controlUnderTest, "networkSelectionCheckbox_Ethereum")
mouseClick(checkBox)
compare(controlUnderTest.checkState, Qt.Unchecked)
controlUnderTest.showIndicator = false
mouseClick(controlUnderTest)
compare(controlUnderTest.checkState, Qt.Unchecked)
mouseMove(controlUnderTest, controlUnderTest.width / 2, controlUnderTest.height / 2)
waitForRendering(controlUnderTest)
waitForItemPolished(controlUnderTest)
compare(controlUnderTest.sensor.containsMouse, true)
// manual selection works
controlUnderTest.checkState = Qt.Checked
compare(controlUnderTest.checkState, Qt.Checked)
controlUnderTest.checkState = Qt.Unchecked
compare(controlUnderTest.checkState, Qt.Unchecked)
}
}
}

View File

@ -50,6 +50,7 @@ Loader {
StatusRoundedImage {
id: statusRoundImage
objectName: "statusRoundImage"
width: parent.width
height: parent.height
image.source: root.asset.isImage ? root.asset.name : ""
@ -80,6 +81,7 @@ Loader {
id: roundedIcon
StatusRoundIcon {
objectName: "statusRoundIcon"
asset.bgRadius: root.asset.bgRadius
asset.bgWidth: root.asset.bgWidth
asset.bgHeight: root.asset.bgHeight

View File

@ -59,7 +59,8 @@ StatusComboBox {
root.multiSelection
NetworkModelHelpers.getChainIconUrl(root.flatNetworks, d.currentIndex)
}
readonly property bool allSelected: enabledFlatNetworks.count === root.flatNetworks.count
readonly property bool allSelected: root.preferredNetworksMode ? root.preferredSharingNetworks.length === root.flatNetworks.count :
enabledFlatNetworks.count === root.flatNetworks.count
readonly property bool noneSelected: enabledFlatNetworks.count === 0
// Persist selection between selectPopupLoader reloads
@ -67,7 +68,14 @@ StatusComboBox {
property SortFilterProxyModel enabledFlatNetworks: SortFilterProxyModel {
sourceModel: root.flatNetworks
filters: ValueFilter { roleName: "isEnabled"; value: true; enabled: !root.preferredNetworksMode }
filters: [
ValueFilter { roleName: "isEnabled"; value: true; enabled: !root.preferredNetworksMode },
FastExpressionFilter {
expression: root.preferredSharingNetworks.includes(chainId.toString())
expectedRoles: ["chainId"]
enabled: root.preferredNetworksMode
}
]
}
}
@ -128,7 +136,7 @@ StatusComboBox {
visible: (!d.allSelected || !root.showAllSelectedText) && chainRepeater.count > 0
Repeater {
id: chainRepeater
model: root.preferredNetworksMode ? root.flatNetworks: root.multiSelection ? d.enabledFlatNetworks: []
model: root.multiSelection ? d.enabledFlatNetworks: []
delegate: StatusRoundedImage {
id: delegateItem
width: 24

View File

@ -1,96 +1,119 @@
import QtQuick 2.15
import QtQml 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 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
property bool showCheckboxes: true
property bool showRadioButtons: true
// input/output property
property int checkState: Qt.Unchecked
// Needed for preferred sharing networks
property bool preferredNetworksMode: false
property var preferredSharingNetworks: []
property bool allChecked: true
//input property
// Defines the next state of the checkbox when clicked
// By default, it toggles between checked and unchecked
property int nextCheckState: checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
signal toggleNetwork(var network, var model, int index)
required property string iconUrl
property bool showIndicator: true
property bool multiSelection: false
property bool interactive: true
/// Mirrors Nim's UxEnabledState enum from networks/item.nim
enum UxEnabledState {
Enabled,
AllEnabled,
Disabled
}
// output signal
// Emitted when the checkbox is clicked
// This signal is useful when the check state needs to change
// only after processing the toggle event E.g backend call
signal toggled
objectName: model.chainName
title: model.chainName
objectName: root.title
asset.height: 24
asset.width: 24
asset.isImage: true
asset.name: Style.svg(model.iconUrl)
asset.name: root.iconUrl
onClicked: {
if(!root.singleSelection.enabled) {
checkBox.nextCheckState()
} else if(!radioButton.checked) { // Don't allow uncheck
root.toggleNetwork(({chainId: model.chainId, chainName: model.chainName, iconUrl: model.iconUrl}), root.networkModel, model.index)
d.toggled()
}
leftPadding: 16
rightPadding: 16
statusListItemTitleArea.anchors.leftMargin: 12
highlighted: (d.checkState !== Qt.Unchecked && !showIndicator)
Binding on bgColor {
when: highlighted && !root.sensor.containsMouse
value: root.interactive ? Theme.palette.baseColor4 : Theme.palette.primaryColor3
restoreMode: Binding.RestoreBindingOrValue
}
onCheckStateChanged: {
if (checkState !== d.checkState) {
d.checkState = checkState
}
}
leftPadding: 12
rightPadding: 0
statusListItemTitleArea.anchors.leftMargin: 12
components: [
StatusCheckBox {
id: checkBox
objectName: "networkSelectionCheckbox_" + model.chainName
tristate: true
visible: !root.singleSelection.enabled && root.showCheckboxes
checkState: {
if(root.preferredNetworksMode) {
return root.allChecked ? Qt.PartiallyChecked : preferredSharingNetworks.includes(model.chainId.toString()) ? Qt.Checked : Qt.Unchecked
}
else if(root.useEnabledRole) {
return model.isEnabled ? Qt.Checked : Qt.Unchecked
} else if (model.enabledState === NetworkSelectItemDelegate.UxEnabledState.Enabled) {
return Qt.Checked
} else {
if( model.enabledState === NetworkSelectItemDelegate.UxEnabledState.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 && root.showRadioButtons
size: StatusRadioButton.Size.Large
ButtonGroup.group: root.radioButtonGroup
checked: root.singleSelection.currentModel === root.networkModel && root.singleSelection.currentIndex === model.index
onToggled: {
if(checked) {
root.toggleNetwork(({chainId: model.chainId, chainName: model.chainName, iconUrl: model.iconUrl}), root.networkModel, model.index)
}
}
Loader {
id: indicatorLoader
sourceComponent: root.multiSelection ? checkBoxComponent : radioButtonComponent
active: root.showIndicator
}
]
Component {
id: checkBoxComponent
StatusCheckBox {
id: checkBox
objectName: "networkSelectionCheckbox_" + root.title
checkState: d.checkState
tristate: true
nextCheckState: () => d.checkState
enabled: root.interactive
onClicked: {
d.toggled()
}
}
}
Component {
id: radioButtonComponent
StatusRadioButton {
id: radioButton
objectName: "networkSelectionRadioButton_" + root.title
size: StatusRadioButton.Size.Large
checked: d.checkState !== Qt.Unchecked
enabled: root.interactive
onClicked: {
d.toggled()
}
}
}
QtObject {
id: d
property int checkState: root.checkState
function toggled() {
if (!root.interactive) {
return
}
d.checkState = root.nextCheckState
root.toggled()
}
onCheckStateChanged: {
if (checkState !== root.checkState) {
root.checkState = checkState
}
}
}
}

View File

@ -75,7 +75,7 @@ StatusDialog {
preferredSharingNetworks: root.preferredSharingNetworks
useEnabledRole: root.useEnabledRole
singleSelection: d.singleSelection
onToggleNetwork: {
onToggleNetwork: (network, index) => {
root.toggleNetwork(network, index)
if(d.singleSelection.enabled)
close()

View File

@ -136,6 +136,13 @@ StatusDialog {
networkFilter.setChain(root.swapInputParamsForm.selectedNetworkChainId)
}
}
Connections {
target: root.swapInputParamsForm
function onSelectedNetworkChainIdChanged() {
networkFilter.setChain(root.swapInputParamsForm.selectedNetworkChainId)
}
}
}
}

View File

@ -1,6 +1,7 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
@ -24,21 +25,71 @@ StatusListView {
signal toggleNetwork(var network, int index)
/// Mirrors Nim's UxEnabledState enum from networks/item.nim
enum UxEnabledState {
Enabled,
AllEnabled,
Disabled
}
model: root.flatNetworks
delegate: NetworkSelectItemDelegate {
id: delegateItem
required property var model
readonly property int multiSelectCheckState: {
if(root.preferredNetworksMode) {
return root.preferredSharingNetworks.length === root.count ?
Qt.PartiallyChecked :
root.preferredSharingNetworks.includes(model.chainId.toString()) ? Qt.Checked : Qt.Unchecked
}
else if(root.useEnabledRole) {
return model.isEnabled ? Qt.Checked : Qt.Unchecked
} else if (model.enabledState === NetworkSelectionView.UxEnabledState.Enabled) {
return Qt.Checked
} else {
if( model.enabledState === NetworkSelectionView.UxEnabledState.AllEnabled) {
return Qt.PartiallyChecked
} else {
return Qt.Unchecked
}
}
}
readonly property int singleSelectCheckState: {
if (root.singleSelection.currentModel === root.model && root.singleSelection.currentIndex === model.index)
return Qt.Checked
return Qt.Unchecked
}
implicitHeight: 48
implicitWidth: root.width
radioButtonGroup: radioBtnGroup
networkModel: root.model
useEnabledRole: root.useEnabledRole
singleSelection: root.singleSelection
onToggleNetwork: (network, model, index) => root.toggleNetwork(network, index)
preferredNetworksMode: root.preferredNetworksMode
preferredSharingNetworks: root.preferredSharingNetworks
allChecked: root.preferredSharingNetworks.length === root.count
showCheckboxes: root.showCheckboxes
showRadioButtons: root.showRadioButtons
title: model.chainName
iconUrl: Style.svg(model.iconUrl)
showIndicator: (multiSelection && root.showCheckboxes) || (!multiSelection && root.showRadioButtons)
multiSelection: !root.singleSelection.enabled
Binding on checkState {
when: root.singleSelection.enabled
value: singleSelectCheckState
}
Binding on checkState {
when: !root.singleSelection.enabled
value: multiSelectCheckState
}
nextCheckState: checkState
onToggled: {
if(!root.singleSelection.enabled) {
Qt.callLater(root.toggleNetwork, delegateItem.model, delegateItem.model.index)
} else if(!checkState !== Qt.Checked) { // Don't allow uncheck
checkState = checkState === Qt.Checked ? Qt.Unchecked : Qt.Checked
root.toggleNetwork(delegateItem.model, model.index)
}
}
}
section {
@ -62,8 +113,4 @@ StatusListView {
}
}
}
ButtonGroup {
id: radioBtnGroup
}
}

View File

@ -1,5 +1,6 @@
AssetsDetailView 1.0 AssetsDetailView.qml
CollectiblesView 1.0 CollectiblesView.qml
NetworkSelectionView 1.0 NetworkSelectionView.qml
SavedAddresses 1.0 SavedAddresses.qml
TokenSelectorAssetDelegate 1.0 TokenSelectorAssetDelegate.qml
TokenSelectorView 1.0 TokenSelectorView.qml