feat(@settings): Add wallet settings with network

This commit is contained in:
Anthony Laibe 2022-02-11 10:44:49 +01:00 committed by Anthony Laibe
parent 42da8a2408
commit 9495956a53
23 changed files with 674 additions and 36 deletions

View File

@ -218,7 +218,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.mailserversService,
result.nodeService,
result.gifService,
result.ensService
result.ensService,
result.networkService,
)
# Do connections

View File

@ -47,6 +47,7 @@ import ../../../app_service/service/devices/service as devices_service
import ../../../app_service/service/mailservers/service as mailservers_service
import ../../../app_service/service/gif/service as gif_service
import ../../../app_service/service/ens/service as ens_service
import ../../../app_service/service/network/service as network_service
import ../../core/eventemitter
@ -103,7 +104,8 @@ proc newModule*[T](
mailserversService: mailservers_service.Service,
nodeService: node_service.Service,
gifService: gif_service.Service,
ensService: ens_service.Service
ensService: ens_service.Service,
networkService: network_service.Service,
): Module[T] =
result = Module[T]()
result.delegate = delegate
@ -136,9 +138,11 @@ proc newModule*[T](
)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService,
dappPermissionsService, providerService)
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService,
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
devicesService, mailserversService, chatService, ensService, walletAccountService)
result.profileSectionModule = profile_section_module.newModule(
result, events, accountsService, settingsService,
profileService, contactsService, aboutService, languageService, privacyService, nodeConfigurationService,
devicesService, mailserversService, chatService, ensService, walletAccountService, networkService,
)
result.stickersModule = stickers_module.newModule(result, events, stickersService)
result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService,
messageService)

View File

@ -80,6 +80,8 @@ method ensUsernamesModuleDidLoad*(self: AccessInterface) {.base.} =
method getEnsUsernamesModule*(self: AccessInterface): QVariant {.base.} =
raise newException(ValueError, "No implementation available")
method walletModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this

View File

@ -15,6 +15,7 @@ import ../../../../app_service/service/mailservers/service as mailservers_servic
import ../../../../app_service/service/chat/service as chat_service
import ../../../../app_service/service/ens/service as ens_service
import ../../../../app_service/service/wallet_account/service_interface as wallet_account_service
import ../../../../app_service/service/network/service as network_service
import ./profile/module as profile_module
import ./contacts/module as contacts_module
@ -26,6 +27,7 @@ import ./devices/module as devices_module
import ./sync/module as sync_module
import ./notifications/module as notifications_module
import ./ens_usernames/module as ens_usernames_module
import ./wallet/module as wallet_module
export io_interface
@ -47,6 +49,7 @@ type
syncModule: sync_module.AccessInterface
notificationsModule: notifications_module.AccessInterface
ensUsernamesModule: ens_usernames_module.AccessInterface
walletModule: wallet_module.AccessInterface
proc newModule*[T](delegate: T,
events: EventEmitter,
@ -62,9 +65,9 @@ proc newModule*[T](delegate: T,
mailserversService: mailservers_service.Service,
chatService: chat_service.Service,
ensService: ens_service.Service,
walletAccountService: wallet_account_service.ServiceInterface
):
Module[T] =
walletAccountService: wallet_account_service.ServiceInterface,
networkService: network_service.Service,
): Module[T] =
result = Module[T]()
result.delegate = delegate
result.view = view.newView(result)
@ -81,8 +84,10 @@ proc newModule*[T](delegate: T,
result.devicesModule = devices_module.newModule(result, events, settingsService, devicesService)
result.syncModule = sync_module.newModule(result, events, settingsService, mailserversService)
result.notificationsModule = notifications_module.newModule(result, events, chatService)
result.ensUsernamesModule = ens_usernames_module.newModule(result, events, settingsService, ensService,
walletAccountService)
result.ensUsernamesModule = ens_usernames_module.newModule(
result, events, settingsService, ensService, walletAccountService
)
result.walletModule = wallet_module.newModule(result, events, networkService)
singletonInstance.engine.setRootContextProperty("profileSectionModule", result.viewVariant)
@ -95,6 +100,7 @@ method delete*[T](self: Module[T]) =
self.advancedModule.delete
self.devicesModule.delete
self.syncModule.delete
self.walletModule.delete
self.view.delete
self.viewVariant.delete
@ -112,6 +118,7 @@ method load*[T](self: Module[T]) =
self.syncModule.load()
self.notificationsModule.load()
self.ensUsernamesModule.load()
self.walletModule.load()
method isLoaded*[T](self: Module[T]): bool =
return self.moduleLoaded
@ -147,6 +154,9 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
if(not self.ensUsernamesModule.isLoaded()):
return
if(not self.walletModule.isLoaded()):
return
self.moduleLoaded = true
self.delegate.profileSectionDidLoad()
@ -159,6 +169,9 @@ method profileModuleDidLoad*[T](self: Module[T]) =
method getProfileModule*[T](self: Module[T]): QVariant =
self.profileModule.getModuleAsVariant()
method walletModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
method contactsModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()

View File

@ -0,0 +1,3 @@
# Defines how parent module accesses this module
include ./private_interfaces/module_base_interface
include ./private_interfaces/module_access_interface

View File

@ -0,0 +1,48 @@
import NimQml
import ./io_interface
import ../../../../global/global_singleton
import ../../../../core/eventemitter
import ../../../../../app_service/service/network/service as network_service
import ../io_interface as delegate_interface
import ./networks/module as networks_module
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
moduleLoaded: bool
networksModule: networks_module.AccessInterface
proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
networkService: network_service.Service,
): Module =
result = Module()
result.delegate = delegate
result.moduleLoaded = false
result.networksModule = networks_module.newModule(result, events, networkService)
method delete*(self: Module) =
self.networksModule.delete
method load*(self: Module) =
self.networksModule.load()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
proc checkIfModuleDidLoad(self: Module) =
if(not self.networksModule.isLoaded()):
return
self.moduleLoaded = true
self.delegate.walletModuleDidLoad()
method networksModuleDidLoad*(self: Module) =
self.checkIfModuleDidLoad()

View File

@ -0,0 +1,31 @@
import ./controller_interface
import ../../../../../core/eventemitter
import ../../../../../../app_service/service/network/service as network_service
import ./io_interface
export controller_interface
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
events: EventEmitter
networkService: network_service.Service
proc newController*(
delegate: io_interface.AccessInterface,
events: EventEmitter,
networkService: network_service.Service
): Controller =
result = Controller()
result.delegate = delegate
result.events = events
result.networkService = networkService
method delete*(self: Controller) =
discard
method init*(self: Controller) =
discard
method getNetworks*(self: Controller): seq[NetworkDto] =
return self.networkService.getNetworks()

View File

@ -0,0 +1,14 @@
import ../../../../../../app_service/service/network/dto
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getNetworks*(self: AccessInterface): seq[NetworkDto] {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,27 @@
import NimQml
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method load*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
# View Delegate Interface
# Delegate for the view must be declared here due to use of QtObject and multi
# inheritance, which is not well supported in Nim.
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.
DelegateInterface* = concept c
c.walletSectionDidLoad()

View File

@ -0,0 +1,74 @@
import strformat
type
Item* = object
chainId: int
nativeCurrencyDecimals: int
layer: int
chainName: string
rpcURL: string
blockExplorerURL: string
nativeCurrencyName: string
nativeCurrencySymbol: string
isTest: bool
proc initItem*(
chainId: int,
nativeCurrencyDecimals: int,
layer: int,
chainName: string,
rpcURL: string,
blockExplorerURL: string,
nativeCurrencyName: string,
nativeCurrencySymbol: string,
isTest: bool
): Item =
result.chainId = chainId
result.nativeCurrencyDecimals = nativeCurrencyDecimals
result.layer = layer
result.chainName = chainName
result.rpcURL = rpcURL
result.blockExplorerURL = blockExplorerURL
result.nativeCurrencyName = nativeCurrencyName
result.nativeCurrencySymbol = nativeCurrencySymbol
result.isTest = isTest
proc `$`*(self: Item): string =
result = fmt"""NetworkItem(
chainId: {self.chainId},
chainName: {self.chainName},
layer: {self.layer},
nativeCurrencyDecimals: {self.nativeCurrencyDecimals},
rpcURL: {self.rpcURL},
blockExplorerURL:{self.blockExplorerURL},
nativeCurrencyName:{self.nativeCurrencyName},
nativeCurrencySymbol:{self.nativeCurrencySymbol},
isTest:{self.isTest}
]"""
proc getChainId*(self: Item): int =
return self.chainId
proc getNativeCurrencyDecimals*(self: Item): int =
return self.nativeCurrencyDecimals
proc getLayer*(self: Item): int =
return self.layer
proc getChainName*(self: Item): string =
return self.chainName
proc getRpcURL*(self: Item): string =
return self.rpcURL
proc getBlockExplorerURL*(self: Item): string =
return self.blockExplorerURL
proc getNativeCurrencyName*(self: Item): string =
return self.nativeCurrencyName
proc getNativeCurrencySymbol*(self: Item): string =
return self.nativeCurrencySymbol
proc getIsTest*(self: Item): bool =
return self.isTest

View File

@ -0,0 +1,96 @@
import NimQml, Tables, strutils, strformat
import ./item
type
ModelRole {.pure.} = enum
ChainId = UserRole + 1,
NativeCurrencyDecimals
Layer
ChainName
RpcURL
BlockExplorerURL
NativeCurrencyName
NativeCurrencySymbol
IsTest
QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
proc delete(self: Model) =
self.items = @[]
self.QAbstractListModel.delete
proc setup(self: Model) =
self.QAbstractListModel.setup
proc newModel*(): Model =
new(result, delete)
result.setup
proc `$`*(self: Model): string =
for i in 0 ..< self.items.len:
result &= fmt"""[{i}]:({$self.items[i]})"""
proc countChanged(self: Model) {.signal.}
proc getCount(self: Model): int {.slot.} =
self.items.len
QtProperty[int] count:
read = getCount
notify = countChanged
method rowCount(self: Model, index: QModelIndex = nil): int =
return self.items.len
method roleNames(self: Model): Table[int, string] =
{
ModelRole.ChainId.int:"chainId",
ModelRole.NativeCurrencyDecimals.int:"nativeCurrencyDecimals",
ModelRole.Layer.int:"layer",
ModelRole.ChainName.int:"chainName",
ModelRole.RpcURL.int:"rpcURL",
ModelRole.BlockExplorerURL.int:"blockExplorerURL",
ModelRole.NativeCurrencyName.int:"nativeCurrencyName",
ModelRole.NativeCurrencySymbol.int:"nativeCurrencySymbol",
ModelRole.IsTest.int:"isTest",
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
if (not index.isValid):
return
if (index.row < 0 or index.row >= self.items.len):
return
let item = self.items[index.row]
let enumRole = role.ModelRole
case enumRole:
of ModelRole.ChainId:
result = newQVariant(item.getChainId())
of ModelRole.NativeCurrencyDecimals:
result = newQVariant(item.getNativeCurrencyDecimals())
of ModelRole.Layer:
result = newQVariant(item.getLayer())
of ModelRole.ChainName:
result = newQVariant(item.getChainName())
of ModelRole.RpcURL:
result = newQVariant(item.getRpcURL())
of ModelRole.BlockExplorerURL:
result = newQVariant(item.getBlockExplorerURL())
of ModelRole.NativeCurrencyName:
result = newQVariant(item.getNativeCurrencyName())
of ModelRole.NativeCurrencySymbol:
result = newQVariant(item.getNativeCurrencySymbol())
of ModelRole.IsTest:
result = newQVariant(item.getIsTest())
proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel()
self.items = items
self.endResetModel()
self.countChanged()

View File

@ -0,0 +1,49 @@
import NimQml
import ../io_interface as delegate_interface
import io_interface, view, controller
import ../../../../../global/global_singleton
import ../../../../../core/eventemitter
import ../../../../../../app_service/service/network/service as network_service
export io_interface
type
Module* = ref object of io_interface.AccessInterface
delegate: delegate_interface.AccessInterface
view: View
viewVariant: QVariant
controller: controller.AccessInterface
moduleLoaded: bool
proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
networkService: networkService.Service,
): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, networkService)
result.moduleLoaded = false
singletonInstance.engine.setRootContextProperty("profileSectionWalletNetworkModule", result.viewVariant)
method delete*(self: Module) =
self.view.delete
self.viewVariant.delete
self.controller.delete
method load*(self: Module) =
let networks = self.controller.getNetworks()
self.view.load(networks)
method isLoaded*(self: Module): bool =
return self.moduleLoaded
proc checkIfModuleDidLoad(self: Module) =
self.moduleLoaded = true
self.delegate.networksModuleDidLoad()
method viewDidLoad*(self: Module) =
self.checkIfModuleDidLoad()

View File

@ -0,0 +1,73 @@
import NimQml, sequtils, sugar
import ../../../../../../app_service/service/network/dto
import ./io_interface
import ./model
import ./item
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
layer1: Model
layer2: Model
test: Model
proc setup(self: View) =
self.QObject.setup
proc delete*(self: View) =
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.delegate = delegate
result.layer1 = newModel()
result.layer2 = newModel()
result.test = newModel()
result.setup()
proc layer1Changed*(self: View) {.signal.}
proc getLayer1(self: View): QVariant {.slot.} =
return newQVariant(self.layer1)
QtProperty[QVariant] layer1:
read = getLayer1
notify = layer1Changed
proc layer2Changed*(self: View) {.signal.}
proc getLayer2(self: View): QVariant {.slot.} =
return newQVariant(self.layer2)
QtProperty[QVariant] layer2:
read = getLayer2
notify = layer2Changed
proc testChanged*(self: View) {.signal.}
proc getTest(self: View): QVariant {.slot.} =
return newQVariant(self.test)
QtProperty[QVariant] test:
read = getTest
notify = testChanged
proc load*(self: View, networks: seq[NetworkDto]) =
let items = networks.map(n => initItem(
n.chainId,
n.nativeCurrencyDecimals,
n.layer,
n.chainName,
n.rpcURL,
n.blockExplorerURL,
n.nativeCurrencyName,
n.nativeCurrencySymbol,
n.isTest
))
self.layer1.setItems(items.filter(i => i.getLayer() == 1 and not i.getIsTest()))
self.layer2.setItems(items.filter(i => i.getLayer() == 2 and not i.getIsTest()))
self.test.setItems(items.filter(i => i.getIsTest()))
self.delegate.viewDidLoad()

View File

@ -0,0 +1,13 @@
import NimQml
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method load*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method networksModuleDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,5 @@
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
# Since nim doesn't support using concepts in second level nested types we
# define delegate interfaces within access interface.

View File

@ -61,6 +61,12 @@ StatusAppTwoPanelLayout {
profileContentWidth: _internal.profileContentWidth
}
WalletView {
id: walletView
walletStore: profileView.store.walletStore
profileContentWidth: _internal.profileContentWidth
}
PrivacyView {
privacyStore: profileView.store.privacyStore
profileContentWidth: _internal.profileContentWidth

View File

@ -14,7 +14,10 @@ Column {
property alias mainMenuItems: mainMenuItems.model
property alias settingsMenuItems: settingsMenuItems.model
property alias extraMenuItems: extraMenuItems.model
property alias appsMenuItems: appsMenuItems.model
property bool browserMenuItemEnabled: false
property bool appsMenuItemsEnabled: false
signal menuItemClicked(var menu_item)
@ -29,6 +32,24 @@ Column {
}
}
StatusListSectionHeadline {
text: qsTr("Apps")
visible: root.appsMenuItemsEnabled
}
Repeater {
id: appsMenuItems
delegate: StatusNavigationListItem {
id: appsMenuDelegate
itemId: model.menu_id
title: model.text
icon.name: model.icon
selected: Global.currentMenuTab === model.menu_id
onClicked: root.menuItemClicked(model)
visible: root.appsMenuItemsEnabled
}
}
StatusListSectionHeadline { text: qsTr("Settings") }
Repeater {

View File

@ -47,26 +47,31 @@ QtObject {
ensUsernamesModule: profileSectionModuleInst.ensUsernamesModule
}
property WalletStore walletStore: WalletStore {
}
property var dappList: dappPermissionsModule.dapps
property var permissionList: dappPermissionsModule.permissions
property int profile_id: 0
property int contacts_id: 1
property int ens_id: 2
property int privacy_and_security_id: 3
property int appearance_id: 4
property int sound_id: 5
property int language_id: 6
property int notifications_id: 7
property int sync_settings_id: 8
property int devices_settings_id: 9
property int browser_settings_id: 10
property int advanced_id: 11
property int need_help_id: 12
property int about_id: 13
property int signout_id: 14
property int wallet_id: 3
property int privacy_and_security_id: 4
property int appearance_id: 5
property int sound_id: 6
property int language_id: 7
property int notifications_id: 8
property int sync_settings_id: 9
property int devices_settings_id: 10
property int browser_settings_id: 11
property int advanced_id: 12
property int need_help_id: 13
property int about_id: 14
property int signout_id: 15
property bool browserMenuItemEnabled: localAccountSensitiveSettings.isBrowserEnabled
property bool appsMenuItemsEnabled: localAccountSensitiveSettings.isMultiNetworkEnabled
property ListModel mainMenuItems: ListModel {
ListElement {
@ -86,50 +91,58 @@ QtObject {
}
}
property ListModel settingsMenuItems: ListModel {
property ListModel appsMenuItems: ListModel {
ListElement {
menu_id: 3
text: qsTr("Wallet")
icon: "wallet"
}
}
property ListModel settingsMenuItems: ListModel {
ListElement {
menu_id: 4
text: qsTr("Privacy and security")
icon: "security"
}
ListElement {
menu_id: 4
menu_id: 5
text: qsTr("Appearance")
icon: "appearance"
}
ListElement {
menu_id: 5
menu_id: 6
text: qsTr("Sound")
icon: "sound"
}
ListElement {
menu_id: 6
menu_id: 7
text: qsTr("Language")
icon: "language"
}
ListElement {
menu_id: 7
menu_id: 8
text: qsTr("Notifications")
icon: "notification"
}
ListElement {
menu_id: 8
menu_id: 9
text: qsTr("Sync settings")
icon: "mobile"
}
ListElement {
menu_id: 9
menu_id: 10
text: qsTr("Devices settings")
icon: "mobile"
}
ListElement {
menu_id: 10
menu_id: 11
text: qsTr("Browser settings")
icon: "browser"
ifEnabled: "browser"
}
ListElement {
menu_id: 11
menu_id: 12
text: qsTr("Advanced")
icon: "settings"
}
@ -137,17 +150,17 @@ QtObject {
property ListModel extraMenuItems: ListModel {
ListElement {
menu_id: 12
menu_id: 13
text: qsTr("Need help?")
icon: "help"
}
ListElement {
menu_id: 13
menu_id: 14
text: qsTr("About")
icon: "info"
}
ListElement {
menu_id: 14
menu_id: 15
function_name: "exit"
text: qsTr("Sign out & Quit")
icon: "logout"

View File

@ -0,0 +1,9 @@
import QtQuick 2.13
QtObject {
id: root
property var layer1Networks: profileSectionWalletNetworkModule.layer1
property var layer2Networks: profileSectionWalletNetworkModule.layer2
property var testNetworks: profileSectionWalletNetworkModule.test
}

View File

@ -37,9 +37,10 @@ Item {
mainMenuItems: store.mainMenuItems
settingsMenuItems: store.settingsMenuItems
extraMenuItems: store.extraMenuItems
appsMenuItems: store.appsMenuItems
browserMenuItemEnabled: store.browserMenuItemEnabled
appsMenuItemsEnabled: store.appsMenuItemsEnabled
onMenuItemClicked: {
if (!!menu_item.function_name && menu_item.function_name === "exit") {
return confirmDialog.open()

View File

@ -0,0 +1,65 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import utils 1.0
import shared 1.0
import shared.panels 1.0
import shared.popups 1.0
import shared.status 1.0
import "../stores"
import "../controls"
import "../popups"
import "../panels"
import "./wallet"
ScrollView {
id: root
property int profileContentWidth
height: parent.height
width: parent.width
contentHeight: advancedContainer.height + 100
clip: true
property WalletStore walletStore
Item {
id: advancedContainer
width: profileContentWidth
anchors.horizontalCenter: parent.horizontalCenter
height: stackContainer.height
StackLayout {
id: stackContainer
anchors.fill: parent
currentIndex: 0
onCurrentIndexChanged: {
if(visibleChildren[0] === ensContainer){
ensContainer.goToStart();
}
}
MainView {
walletStore: root.walletStore
onGoToNetworksView: {
stackContainer.currentIndex = 1
}
}
NetworksView {
walletStore: root.walletStore
anchors.fill: parent
onGoBack: {
stackContainer.currentIndex = 0
}
}
}
}
}

View File

@ -0,0 +1,22 @@
import QtQuick 2.13
import shared.status 1.0
import "../../stores"
Column {
id: root
anchors.top: parent.top
anchors.topMargin: 64
anchors.left: parent.left
anchors.right: parent.right
property WalletStore walletStore
signal goToNetworksView()
StatusSettingsLineButton {
text: qsTr("Networks")
onClicked: goToNetworksView()
}
}

View File

@ -0,0 +1,48 @@
import QtQuick 2.13
import shared.status 1.0
import "../../stores"
import utils 1.0
Column {
id: root
anchors.top: parent.top
anchors.topMargin: 64
anchors.left: parent.left
anchors.right: parent.right
property WalletStore walletStore
signal goBack
ListView {
id: layer1List
model: walletStore.layer1Networks
width: parent.width
height: layer1List.childrenRect.height
delegate: StatusSettingsLineButton {
text: model.chainName
}
}
ListView {
id: layer2List
model: walletStore.layer2Networks
width: parent.width
height: layer2List.childrenRect.height
delegate: StatusSettingsLineButton {
text: model.chainName
}
}
ListView {
id: testList
model: walletStore.testNetworks
width: parent.width
height: testList.childrenRect.height
delegate: StatusSettingsLineButton {
text: model.chainName
}
}
}