diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index 4bd0506ee4..59517932b0 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -155,7 +155,7 @@ proc newModule*[T]( result.appSearchModule = app_search_module.newModule(result, events, contactsService, chatService, communityService, messageService) result.nodeSectionModule = node_section_module.newModule(result, events, settingsService, nodeService, nodeConfigurationService) - result.networksModule = networks_module.newModule(result, events, networkService, walletAccountService) + result.networksModule = networks_module.newModule(result, events, networkService, walletAccountService, settingsService) method delete*[T](self: Module[T]) = self.chatSectionModule.delete diff --git a/src/app/modules/main/networks/controller.nim b/src/app/modules/main/networks/controller.nim index 6f547c02e7..71840674f3 100644 --- a/src/app/modules/main/networks/controller.nim +++ b/src/app/modules/main/networks/controller.nim @@ -1,6 +1,7 @@ import ../../../core/eventemitter import ../../../../app_service/service/network/service as network_service import ../../../../app_service/service/wallet_account/service as wallet_account_service +import ../../../../app_service/service/settings/service as settings_service import ./io_interface @@ -10,18 +11,21 @@ type events: EventEmitter networkService: network_service.Service walletAccountService: wallet_account_service.Service + settingsService: settings_service.Service proc newController*( delegate: io_interface.AccessInterface, events: EventEmitter, networkService: network_service.Service, walletAccountService: wallet_account_service.Service, + settingsService: settings_service.Service, ): Controller = result = Controller() result.delegate = delegate result.events = events result.networkService = networkService result.walletAccountService = walletAccountService + result.settingsService = settingsService proc delete*(self: Controller) = discard @@ -34,4 +38,10 @@ proc getNetworks*(self: Controller): seq[NetworkDto] = return self.networkService.getNetworks() proc toggleNetwork*(self: Controller, chainId: int) = - self.walletAccountService.toggleNetworkEnabled(chainId) \ No newline at end of file + self.walletAccountService.toggleNetworkEnabled(chainId) + +proc areTestNetworksEnabled*(self: Controller): bool = + return self.settingsService.areTestNetworksEnabled() + +proc toggleTestNetworksEnabled*(self: Controller) = + self.walletAccountService.toggleTestNetworksEnabled() \ No newline at end of file diff --git a/src/app/modules/main/networks/io_interface.nim b/src/app/modules/main/networks/io_interface.nim index 3d4b82859f..1a8a936939 100644 --- a/src/app/modules/main/networks/io_interface.nim +++ b/src/app/modules/main/networks/io_interface.nim @@ -24,3 +24,6 @@ method toggleNetwork*(self: AccessInterface, chainId: int) {.base.} = method refreshNetworks*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") + +method toggleTestNetworksEnabled*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/src/app/modules/main/networks/module.nim b/src/app/modules/main/networks/module.nim index e3568e43d3..89d5d946cc 100644 --- a/src/app/modules/main/networks/module.nim +++ b/src/app/modules/main/networks/module.nim @@ -5,6 +5,7 @@ import ../../../global/global_singleton import ../../../core/eventemitter import ../../../../app_service/service/network/service as network_service import ../../../../app_service/service/wallet_account/service as wallet_account_service +import ../../../../app_service/service/settings/service as settings_service export io_interface @@ -21,12 +22,13 @@ proc newModule*( events: EventEmitter, networkService: networkService.Service, walletAccountService: wallet_account_service.Service, + settingsService: settings_service.Service, ): Module = result = Module() result.delegate = delegate result.view = view.newView(result) result.viewVariant = newQVariant(result.view) - result.controller = controller.newController(result, events, networkService, walletAccountService) + result.controller = controller.newController(result, events, networkService, walletAccountService, settingsService) result.moduleLoaded = false singletonInstance.engine.setRootContextProperty("networksModule", result.viewVariant) @@ -42,6 +44,7 @@ method refreshNetworks*(self: Module) = method load*(self: Module) = self.controller.init() + self.view.setAreTestNetworksEnabled(self.controller.areTestNetworksEnabled()) self.refreshNetworks() method isLoaded*(self: Module): bool = @@ -55,4 +58,11 @@ method viewDidLoad*(self: Module) = self.checkIfModuleDidLoad() method toggleNetwork*(self: Module, chainId: int) = - self.controller.toggleNetwork(chainId) \ No newline at end of file + self.controller.toggleNetwork(chainId) + +method areTestNetworksEnabled*(self: Module): bool = + return self.controller.areTestNetworksEnabled() + +method toggleTestNetworksEnabled*(self: Module) = + self.controller.toggleTestNetworksEnabled() + self.refreshNetworks() \ No newline at end of file diff --git a/src/app/modules/main/networks/view.nim b/src/app/modules/main/networks/view.nim index 5406b45d8c..cd28c03441 100644 --- a/src/app/modules/main/networks/view.nim +++ b/src/app/modules/main/networks/view.nim @@ -12,7 +12,7 @@ QtObject: enabled: Model layer1: Model layer2: Model - test: Model + areTestNetworksEnabled: bool proc setup(self: View) = self.QObject.setup @@ -25,10 +25,22 @@ QtObject: result.delegate = delegate result.layer1 = newModel() result.layer2 = newModel() - result.test = newModel() result.enabled = newModel() result.setup() + proc areTestNetworksEnabledChanged*(self: View) {.signal.} + + proc getAreTestNetworksEnabled(self: View): QVariant {.slot.} = + return newQVariant(self.areTestNetworksEnabled) + + QtProperty[QVariant] areTestNetworksEnabled: + read = getAreTestNetworksEnabled + notify = areTestNetworksEnabledChanged + + proc setAreTestNetworksEnabled*(self: View, areTestNetworksEnabled: bool) = + self.areTestNetworksEnabled = areTestNetworksEnabled + self.areTestNetworksEnabledChanged() + proc layer1Changed*(self: View) {.signal.} proc getLayer1(self: View): QVariant {.slot.} = @@ -47,15 +59,6 @@ QtObject: 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 enabledChanged*(self: View) {.signal.} proc getEnabled(self: View): QVariant {.slot.} = @@ -78,16 +81,20 @@ QtObject: n.isTest, n.enabled, )) - 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.layer1.setItems(items.filter(i => i.getLayer() == 1)) + self.layer2.setItems(items.filter(i => i.getLayer() == 2)) self.enabled.setItems(items.filter(i => i.getIsEnabled())) self.layer1Changed() self.layer2Changed() - self.testChanged() + self.enabledChanged() self.delegate.viewDidLoad() proc toggleNetwork*(self: View, chainId: int) {.slot.} = - self.delegate.toggleNetwork(chainId) \ No newline at end of file + self.delegate.toggleNetwork(chainId) + + proc toggleTestNetworksEnabled*(self: View) {.slot.} = + self.delegate.toggleTestNetworksEnabled() + self.areTestNetworksEnabled = not self.areTestNetworksEnabled + self.areTestNetworksEnabledChanged() \ No newline at end of file diff --git a/src/app_service/service/network/service.nim b/src/app_service/service/network/service.nim index ecca44d4bc..c8f66c57d7 100644 --- a/src/app_service/service/network/service.nim +++ b/src/app_service/service/network/service.nim @@ -32,7 +32,7 @@ proc newService*(events: EventEmitter, settingsService: settings_service.Service proc init*(self: Service) = discard -proc getNetworks*(self: Service, useCached: bool = true): seq[NetworkDto] = +proc fetchNetworks*(self: Service, useCached: bool = true): seq[NetworkDto] = let cacheIsDirty = not self.networksInited or self.dirty.load if useCached and not cacheIsDirty: result = self.networks @@ -40,16 +40,26 @@ proc getNetworks*(self: Service, useCached: bool = true): seq[NetworkDto] = let response = backend.getEthereumChains(false) if not response.error.isNil: raise newException(Exception, "Error getting networks: " & response.error.message) - result = if response.result.isNil or response.result.kind == JNull: @[] + result = if response.result.isNil or response.result.kind == JNull: @[] else: Json.decode($response.result, seq[NetworkDto]) self.dirty.store(false) self.networks = result self.networksInited = true +proc getNetworks*(self: Service): seq[NetworkDto] = + let testNetworksEnabled = self.settingsService.areTestNetworksEnabled() + + for network in self.fetchNetworks(): + if testNetworksEnabled and network.isTest: + result.add(network) + + if not testNetworksEnabled and not network.isTest: + result.add(network) + proc getEnabledNetworks*(self: Service): seq[NetworkDto] = if not singletonInstance.localAccountSensitiveSettings.getIsMultiNetworkEnabled(): let currentNetworkType = self.settingsService.getCurrentNetwork().toNetworkType() - for network in self.getNetworks(): + for network in self.fetchNetworks(): if currentNetworkType.toChainId() == network.chainId: return @[network] @@ -67,12 +77,12 @@ proc deleteNetwork*(self: Service, network: NetworkDto) = self.dirty.store(true) proc getNetwork*(self: Service, chainId: int): NetworkDto = - for network in self.getNetworks(): + for network in self.fetchNetworks(): if chainId == network.chainId: return network proc getNetwork*(self: Service, networkType: NetworkType): NetworkDto = - for network in self.getNetworks(): + for network in self.fetchNetworks(): if networkType.toChainId() == network.chainId: return network diff --git a/src/app_service/service/settings/dto/settings.nim b/src/app_service/service/settings/dto/settings.nim index 0a7a6c4347..8206787a1b 100644 --- a/src/app_service/service/settings/dto/settings.nim +++ b/src/app_service/service/settings/dto/settings.nim @@ -45,6 +45,7 @@ const KEY_GIF_FAVORITES* = "gifs/favorite-gifs" const KEY_GIF_RECENTS* = "gifs/recent-gifs" const KEY_GIF_API_KEY* = "gifs/api-key" const KEY_DISPLAY_NAME = "display-name" +const KEY_TEST_NETWORKS_ENABLED* = "test-networks-enabled?" const PROFILE_PICTURES_VISIBILITY_CONTACTS_ONLY* = 1 const PROFILE_PICTURES_VISIBILITY_EVERYONE* = 2 @@ -120,6 +121,7 @@ type autoMessageEnabled*: bool gifRecents*: JsonNode gifFavorites*: JsonNode + testNetworksEnabled*: bool proc toUpstreamConfig*(jsonObj: JsonNode): UpstreamConfig = discard jsonObj.getProp("Enabled", result.Enabled) @@ -209,6 +211,7 @@ proc toSettingsDto*(jsonObj: JsonNode): SettingsDto = discard jsonObj.getProp(KEY_AUTO_MESSAGE_ENABLED, result.autoMessageEnabled) discard jsonObj.getProp(KEY_GIF_RECENTS, result.gifRecents) discard jsonObj.getProp(KEY_GIF_FAVORITES, result.gifFavorites) + discard jsonObj.getProp(KEY_TEST_NETWORKS_ENABLED, result.testNetworksEnabled) var pinnedMailserverObj: JsonNode if(jsonObj.getProp(KEY_PINNED_MAILSERVERS, pinnedMailserverObj)): diff --git a/src/app_service/service/settings/service.nim b/src/app_service/service/settings/service.nim index ae11f2850c..3474802542 100644 --- a/src/app_service/service/settings/service.nim +++ b/src/app_service/service/settings/service.nim @@ -451,4 +451,14 @@ proc autoMessageEnabled*(self: Service): bool = proc getWakuBloomFilterMode*(self: Service): bool = return self.settings.wakuBloomFilterMode +method areTestNetworksEnabled*(self: Service): bool = + return self.settings.testNetworksEnabled + +method toggleTestNetworksEnabled*(self: Service): bool = + let newValue = not self.settings.testNetworksEnabled + if(self.saveSetting(KEY_TEST_NETWORKS_ENABLED, newValue)): + self.settings.testNetworksEnabled = newValue + return true + return false + diff --git a/src/app_service/service/wallet_account/service.nim b/src/app_service/service/wallet_account/service.nim index e3c10002bb..c096cbbec8 100644 --- a/src/app_service/service/wallet_account/service.nim +++ b/src/app_service/service/wallet_account/service.nim @@ -323,6 +323,12 @@ proc toggleNetworkEnabled*(self: Service, chainId: int) = self.refreshBalances() self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled()) +method toggleTestNetworksEnabled*(self: Service) = + discard self.settings_service.toggleTestNetworksEnabled() + self.tokenService.init() + self.refreshBalances() + self.events.emit(SIGNAL_WALLET_ACCOUNT_NETWORK_ENABLED_UPDATED, NetwordkEnabledToggled()) + proc updateWalletAccount*(self: Service, address: string, accountName: string, color: string, emoji: string) = let account = self.accounts[address] status_go_accounts.updateAccount( diff --git a/ui/app/AppLayouts/Profile/stores/WalletStore.qml b/ui/app/AppLayouts/Profile/stores/WalletStore.qml index 2356a392cd..b35b2060c3 100644 --- a/ui/app/AppLayouts/Profile/stores/WalletStore.qml +++ b/ui/app/AppLayouts/Profile/stores/WalletStore.qml @@ -6,10 +6,14 @@ QtObject { property var accountSensitiveSettings: localAccountSensitiveSettings property bool isMultiNetworkEnabled: accountSensitiveSettings.isMultiNetworkEnabled + property var areTestNetworksEnabled: networksModule.areTestNetworksEnabled property var layer1Networks: networksModule.layer1 property var layer2Networks: networksModule.layer2 property var testNetworks: networksModule.test + function toggleTestNetworksEnabled(){ + networksModule.toggleTestNetworksEnabled() + } property var importedAccounts: walletSectionAccounts.imported property var generatedAccounts: walletSectionAccounts.generated diff --git a/ui/app/AppLayouts/Profile/views/WalletView.qml b/ui/app/AppLayouts/Profile/views/WalletView.qml index 18100d057b..d5706dbf2a 100644 --- a/ui/app/AppLayouts/Profile/views/WalletView.qml +++ b/ui/app/AppLayouts/Profile/views/WalletView.qml @@ -3,6 +3,8 @@ import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import QtGraphicalEffects 1.13 +import StatusQ.Controls 0.1 + import utils 1.0 import shared 1.0 import shared.panels 1.0 @@ -15,61 +17,82 @@ import "../popups" import "../panels" import "./wallet" -ScrollView { +Item { id: root property var emojiPopup property WalletStore walletStore - clip: true + anchors.fill: parent - StackLayout { - id: stackContainer + readonly property int mainViewIndex: 0; + readonly property int networksViewIndex: 1; + readonly property int accountViewIndex: 2; + readonly property int dappPermissionViewIndex: 3; - anchors.fill: parent - currentIndex: 0 + StatusBanner { + id: banner + anchors.left: parent.left + anchors.top: parent.top + anchors.right: parent.right + visible: walletStore.areTestNetworksEnabled + type: StatusBanner.Type.Danger + statusText: qsTr("Testnet mode is enabled. All balances, transactions and dApp interactions will be on testnets.") + } - MainView { - id: main - Layout.preferredWidth: 560 - leftPadding: 64 - topPadding: 64 - walletStore: root.walletStore + ScrollView { - onGoToNetworksView: { - stackContainer.currentIndex = 1 + anchors.top: banner.visible ? banner.bottom: parent.top + clip: true + + StackLayout { + id: stackContainer + + anchors.fill: parent + currentIndex: mainViewIndex + + MainView { + id: main + Layout.preferredWidth: 560 + leftPadding: 64 + topPadding: 64 + walletStore: root.walletStore + + onGoToNetworksView: { + stackContainer.currentIndex = networksViewIndex + } + + onGoToAccountView: { + root.walletStore.switchAccountByAddress(address) + stackContainer.currentIndex = accountViewIndex + } + + onGoToDappPermissionsView: { + stackContainer.currentIndex = dappPermissionViewIndex + } } - onGoToAccountView: { - root.walletStore.switchAccountByAddress(address) - stackContainer.currentIndex = 2 + NetworksView { + walletStore: root.walletStore + onGoBack: { + stackContainer.currentIndex = mainViewIndex + } } - onGoToDappPermissionsView: { - stackContainer.currentIndex = 3 + AccountView { + walletStore: root.walletStore + emojiPopup: root.emojiPopup + onGoBack: { + stackContainer.currentIndex = mainViewIndex + } } - } - NetworksView { - walletStore: root.walletStore - onGoBack: { - stackContainer.currentIndex = 0 - } - } - - AccountView { - walletStore: root.walletStore - emojiPopup: root.emojiPopup - onGoBack: { - stackContainer.currentIndex = 0 - } - } - - DappPermissionsView { - walletStore: root.walletStore - onGoBack: { - stackContainer.currentIndex = 0 + DappPermissionsView { + walletStore: root.walletStore + onGoBack: { + stackContainer.currentIndex = mainViewIndex + } } } } -} +} \ No newline at end of file diff --git a/ui/app/AppLayouts/Profile/views/wallet/NetworksView.qml b/ui/app/AppLayouts/Profile/views/wallet/NetworksView.qml index 4a11191fdd..a5d73a6427 100644 --- a/ui/app/AppLayouts/Profile/views/wallet/NetworksView.qml +++ b/ui/app/AppLayouts/Profile/views/wallet/NetworksView.qml @@ -39,7 +39,7 @@ Item { width: 560 Row { - spacing: 250 + spacing: 200 StatusBaseText { id: titleText text: qsTr("Networks") @@ -48,14 +48,12 @@ Item { color: Theme.palette.directColor1 } - StatusButton { - id: addCustomNetworkButton - type: StatusFlatRoundButton.Type.Primary - text: qsTr("Add Custom Network") - onClicked: { - root.goBack() - } + StatusSwitch { + text: qsTr("Testnet Mode") + checked: walletStore.areTestNetworksEnabled + onClicked: walletStore.toggleTestNetworksEnabled() } + } @@ -86,18 +84,22 @@ Item { } } - StatusSectionHeadline { - text: qsTr("Testnets") - topPadding: Style.current.bigPadding - bottomPadding: Style.current.padding + Item { + height: Style.current.bigPadding + width: parent.width } - Repeater { - id: testList - model: walletStore.testNetworks - delegate: WalletNetworkDelegate { - network: model + StatusButton { + // Disable for now + visible: false + anchors.right: parent.right + anchors.rightMargin: Style.current.bigPadding + id: addCustomNetworkButton + type: StatusFlatRoundButton.Type.Primary + text: qsTr("Add Custom Network") + onClicked: { + root.goBack() } } } -} \ No newline at end of file +} diff --git a/vendor/status-go b/vendor/status-go index e67592d556..8f4c8da953 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit e67592d556aa7320ee660ea64e2bfccfbc5166e9 +Subproject commit 8f4c8da9533d1f71359c2e4541b9a47789db209b