fix() don't change global network selection in receive modal

Adds a networks proxy model to be used with the original source model
for visualization and independent selection of isEnabled (as isActive) for a custom
purpose.

Use the proxy in the receive modal dialog for selection of networks
to be included in the address. This way the view follows the original
model but allows independent selection of networks.

Closes: #8180
This commit is contained in:
Stefan 2022-11-12 11:18:18 +02:00 committed by Stefan Dunca
parent 7bd9808476
commit 7d9f13e4bd
7 changed files with 185 additions and 49 deletions

View File

@ -3,7 +3,7 @@ import NimQml, Tables, strutils, strformat
import ./item
type
ModelRole {.pure.} = enum
ModelRole* {.pure.} = enum
ChainId = UserRole + 1,
NativeCurrencyDecimals
Layer
@ -48,7 +48,7 @@ QtObject:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
method rowCount*(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
@ -109,7 +109,7 @@ QtObject:
of ModelRole.Balance:
result = newQVariant(item.getBalance())
proc rowData(self: Model, index: int, column: string): string {.slot.} =
proc rowData*(self: Model, index: int, column: string): string {.slot.} =
if (index >= self.items.len):
return
let item = self.items[index]

View File

@ -0,0 +1,89 @@
import NimQml, Tables, strutils
import ./model
# Proxy data model for the Networks data model with additional role; see isActiveRoleName
# isEnabled values are copied from the original model into isActiveRoleName values
const isActiveRoleName = "isActive"
QtObject:
type
NetworksExtraStoreProxy* = ref object of QAbstractListModel
sourceModel: Model
activeNetworks: seq[bool]
extraRole: tuple[roleId: int, roleName: string]
proc delete(self: NetworksExtraStoreProxy) =
self.sourceModel = nil
self.activeNetworks = @[]
self.QAbstractListModel.delete
proc setup(self: NetworksExtraStoreProxy) =
self.QAbstractListModel.setup
proc updateActiveNetworks(self: NetworksExtraStoreProxy, sourceModel: Model) =
var tmpSeq = newSeq[bool](sourceModel.rowCount())
for i in 0 ..< sourceModel.rowCount():
tmpSeq[i] = sourceModel.data(sourceModel.index(i, 0, newQModelIndex()), ModelRole.IsEnabled.int).boolVal()
self.activeNetworks = tmpSeq
proc newNetworksExtraStoreProxy*(sourceModel: Model): NetworksExtraStoreProxy =
new(result, delete)
result.sourceModel = sourceModel
# assign past last role element
result.extraRole = (0, isActiveRoleName)
for k in sourceModel.roleNames().keys:
if k > result.extraRole.roleId:
result.extraRole.roleId = k
result.extraRole.roleId += 1
result.updateactiveNetworks(sourceModel)
result.setup
signalConnect(result.sourceModel, "countChanged()", result, "onCountChanged()")
proc countChanged(self: NetworksExtraStoreProxy) {.signal.}
# Nimqml doesn't support connecting signals to other signals
proc onCountChanged(self: NetworksExtraStoreProxy) {.slot.} =
self.updateActiveNetworks(self.sourceModel)
self.countChanged()
proc getCount(self: NetworksExtraStoreProxy): int {.slot.} =
return self.sourceModel.rowCount()
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: NetworksExtraStoreProxy, index: QModelIndex = nil): int =
return self.sourceModel.rowCount()
method roleNames(self: NetworksExtraStoreProxy): Table[int, string] =
var srcRoles = self.sourceModel.roleNames()
srcRoles.add(self.extraRole.roleId, self.extraRole.roleName)
return srcRoles
method data(self: NetworksExtraStoreProxy, index: QModelIndex, role: int): QVariant =
if role == self.extraRole.roleId:
if index.row() < 0 or index.row() >= self.activeNetworks.len:
return QVariant()
return newQVariant(self.activeNetworks[index.row()])
return self.sourceModel.data(index, role)
method setData*(self: NetworksExtraStoreProxy, index: QModelIndex, value: QVariant, role: int): bool =
if role == self.extraRole.roleId:
if index.row() < 0 or index.row() >= self.activeNetworks.len:
return false
self.activeNetworks[index.row()] = value.boolVal()
self.dataChanged(index, index, [self.extraRole.roleId])
return true
return self.sourceModel.setData(index, value, role)
proc rowData(self: NetworksExtraStoreProxy, index: int, column: string): string {.slot.} =
if column == isActiveRoleName:
if index < 0 or index >= self.activeNetworks.len:
return ""
return $self.activeNetworks[index]
return self.sourceModel.rowData(index, column)

View File

@ -3,6 +3,7 @@ import Tables, NimQml, sequtils, sugar
import ../../../../app_service/service/network/dto
import ./io_interface
import ./model
import ./networks_extra_store_proxy
import ./item
QtObject:
@ -14,6 +15,9 @@ QtObject:
layer1: Model
layer2: Model
areTestNetworksEnabled: bool
# Lazy initized but here to keep a reference to the object not to be GCed
layer1Proxy: NetworksExtraStoreProxy
layer2Proxy: NetworksExtraStoreProxy
proc setup(self: View) =
self.QObject.setup
@ -28,6 +32,8 @@ QtObject:
result.layer1 = newModel()
result.layer2 = newModel()
result.enabled = newModel()
result.layer1Proxy = nil
result.layer2Proxy = nil
result.setup()
proc areTestNetworksEnabledChanged*(self: View) {.signal.}
@ -118,3 +124,25 @@ QtObject:
self.delegate.toggleTestNetworksEnabled()
self.areTestNetworksEnabled = not self.areTestNetworksEnabled
self.areTestNetworksEnabledChanged()
proc layer1ProxyChanged*(self: View) {.signal.}
proc getLayer1Proxy(self: View): QVariant {.slot.} =
if self.layer1Proxy.isNil:
self.layer1Proxy = newNetworksExtraStoreProxy(self.layer1)
return newQVariant(self.layer1Proxy)
QtProperty[QVariant] layer1Proxy:
read = getLayer1Proxy
notify = layer1ProxyChanged
proc layer2ProxyChanged*(self: View) {.signal.}
proc getLayer2Proxy(self: View): QVariant {.slot.} =
if self.layer2Proxy.isNil:
self.layer2Proxy = newNetworksExtraStoreProxy(self.layer2)
return newQVariant(self.layer2Proxy)
QtProperty[QVariant] layer2Proxy:
read = getLayer2Proxy
notify = layer2ProxyChanged

View File

@ -7,7 +7,6 @@ QtObject {
property var advancedModule
// Advanced Module Properties
property string currentChainId: advancedModule? advancedModule.currentChainId : 0
property string fleet: advancedModule? advancedModule.fleet : ""
property string bloomLevel: advancedModule? advancedModule.bloomLevel : ""
property bool wakuV2LightClientEnabled: advancedModule? advancedModule.wakuV2LightClientEnabled : false

View File

@ -12,7 +12,7 @@ import utils 1.0
// TODO: replace with StatusModal
Popup {
id: popup
id: root
modal: false
width: 360
height: 432
@ -25,6 +25,9 @@ Popup {
property var layer2Networks
property var testNetworks
// If true NetworksExtraStoreProxy expected for layer1Networks and layer2Networks properties
property bool useNetworksExtraStoreProxy: false
signal toggleNetwork(int chainId)
background: Rectangle {
@ -45,8 +48,8 @@ Popup {
contentItem: StatusScrollView {
id: scrollView
contentHeight: content.height
width: popup.width
height: popup.height
width: root.width
height: root.height
padding: 0
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
@ -61,7 +64,7 @@ Popup {
width: parent.width
height: parent.height
objectName: "networkSelectPopupChainRepeaterLayer1"
model: popup.layer1Networks
model: root.layer1Networks
delegate: chainItem
}
@ -80,14 +83,14 @@ Popup {
Repeater {
id: chainRepeater2
model: popup.layer2Networks
model: root.layer2Networks
delegate: chainItem
}
Repeater {
id: chainRepeater3
model: popup.testNetworks
model: root.testNetworks
delegate: chainItem
}
@ -111,10 +114,12 @@ Popup {
components: [
StatusCheckBox {
id: checkBox
checked: model.isEnabled
checked: root.useNetworksExtraStoreProxy ? model.isActive : model.isEnabled
onCheckedChanged: {
if (model.isEnabled !== checked) {
popup.toggleNetwork(model.chainId)
if(root.useNetworksExtraStoreProxy && model.isActive !== checked) {
model.isActive = checked
} else if (model.isEnabled !== checked) {
root.toggleNetwork(model.chainId)
}
}
}

View File

@ -19,14 +19,14 @@ import shared.popups 1.0
import "../stores"
StatusModal {
id: popup
id: root
property var selectedAccount
property string networkPrefix: ""
property string completeAddressWithNetworkPrefix
onSelectedAccountChanged: {
if (selectedAccount.address) {
if (selectedAccount && selectedAccount.address) {
txtWalletAddress.text = selectedAccount.address
}
}
@ -47,23 +47,23 @@ StatusModal {
target: RootStore.enabledNetworks
function onModelReset() {
if(RootStore.enabledNetworks.count === 0)
popup.networkPrefix = ""
root.networkPrefix = ""
}
}
hasFloatingButtons: true
advancedHeaderComponent: AccountsModalHeader {
model: RootStore.accounts
selectedAccount: popup.selectedAccount
selectedAccount: root.selectedAccount
changeSelectedAccount: function(newAccount, newIndex) {
popup.selectedAccount = newAccount
root.selectedAccount = newAccount
}
showAllWalletTypes: true
}
contentItem: Column {
id: layout
width: popup.width
width: root.width
topPadding: Style.current.xlPadding
spacing: Style.current.bigPadding
@ -97,12 +97,16 @@ StatusModal {
flow: Grid.TopToBottom
columns: need2Columns ? 2 : 1
spacing: 5
property var networkProxies: [RootStore.layer1NetworksProxy, RootStore.layer2NetworksProxy]
Repeater {
model: RootStore.enabledNetworks
model: multiChainList.networkProxies.length
delegate: Repeater {
model: multiChainList.networkProxies[index]
delegate: InformationTag {
tagPrimaryLabel.text: model.shortName
tagPrimaryLabel.color: model.chainColor
image.source: Style.svg("tiny/" + model.iconUrl)
visible: model.isActive
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
@ -110,6 +114,7 @@ StatusModal {
}
}
}
}
StatusRoundButton {
width: 32
height: 32
@ -200,15 +205,21 @@ StatusModal {
id: networksLabel
spacing: -1
Repeater {
model: RootStore.enabledNetworks
model: multiChainList.networkProxies.length
delegate: Repeater {
model: multiChainList.networkProxies[index]
delegate: StatusBaseText {
font.pixelSize: 15
color: chainColor
text: shortName + ":"
Component.onCompleted: {
if(index === 0)
popup.networkPrefix = ""
popup.networkPrefix +=text
visible: model.isActive
onVisibleChanged: {
if (visible) {
networkPrefix += text
} else {
networkPrefix = networkPrefix.replace(text, "")
}
}
}
}
}
@ -241,14 +252,16 @@ StatusModal {
NetworkSelectPopup {
id: selectPopup
x: multiChainList.x + Style.current.xlPadding + Style.current.halfPadding
y: centralLayout.y
layer1Networks: RootStore.layer1Networks
layer2Networks: RootStore.layer2Networks
testNetworks: RootStore.testNetworks
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
onToggleNetwork: (chainId) => RootStore.toggleNetwork(chainId)
layer1Networks: RootStore.layer1NetworksProxy
layer2Networks: RootStore.layer2NetworksProxy
testNetworks: RootStore.testNetworks
useNetworksExtraStoreProxy: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
}
states: [
@ -272,8 +285,8 @@ StatusModal {
textToCopy: txtWalletAddress.text
}
PropertyChanges {
target: popup
completeAddressWithNetworkPrefix: popup.selectedAccount.address
target: root
completeAddressWithNetworkPrefix: root.selectedAccount.address
}
},
State {
@ -293,11 +306,11 @@ StatusModal {
}
PropertyChanges {
target: copyToClipBoard
textToCopy: popup.networkPrefix + txtWalletAddress.text
textToCopy: root.networkPrefix + txtWalletAddress.text
}
PropertyChanges {
target: popup
completeAddressWithNetworkPrefix: popup.networkPrefix + popup.selectedAccount.address
target: root
completeAddressWithNetworkPrefix: root.networkPrefix + root.selectedAccount.address
}
}
]

View File

@ -48,6 +48,8 @@ QtObject {
property var testNetworks: networksModule.test
property var enabledNetworks: networksModule.enabled
property var allNetworks: networksModule.all
property var layer1NetworksProxy: networksModule.layer1Proxy
property var layer2NetworksProxy: networksModule.layer2Proxy
property var cryptoRampServicesModel: walletSectionBuySellCrypto.model