feat: implement New tag and decorator for NetworkFilter

This commit is contained in:
Dario Gabriel Lipicar 2025-02-11 10:20:34 -03:00
parent 02c35f8c6a
commit fffaebfffb
No known key found for this signature in database
GPG Key ID: 9625E9494309D203
18 changed files with 238 additions and 7 deletions

View File

@ -21,6 +21,7 @@ type
ShortName ShortName
IsActive IsActive
IsDeactivatable IsDeactivatable
IsNew
QtObject: QtObject:
type type
@ -56,7 +57,8 @@ QtObject:
ModelRole.ShortName.int: "shortName", ModelRole.ShortName.int: "shortName",
ModelRole.ChainColor.int: "chainColor", ModelRole.ChainColor.int: "chainColor",
ModelRole.IsActive.int: "isActive", ModelRole.IsActive.int: "isActive",
ModelRole.IsDeactivatable.int: "isDeactivatable" ModelRole.IsDeactivatable.int: "isDeactivatable",
ModelRole.IsNew.int: "isNew"
}.toTable }.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant = method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -98,6 +100,8 @@ QtObject:
result = newQVariant(item.isActive) result = newQVariant(item.isActive)
of ModelRole.IsDeactivatable: of ModelRole.IsDeactivatable:
result = newQVariant(item.isDeactivatable) result = newQVariant(item.isDeactivatable)
of ModelRole.IsNew:
result = newQVariant(item.isNew)
proc refreshModel*(self: Model) = proc refreshModel*(self: Model) =
self.beginResetModel() self.beginResetModel()

View File

@ -2,7 +2,7 @@ import NimQml, stew/shims/strformat
import sequtils, sugar import sequtils, sugar
import backend/network_types import backend/network_types
import ./rpc_provider_item import ./rpc_provider_item, ./types
export rpc_provider_item export rpc_provider_item
@ -24,6 +24,7 @@ QtObject:
relatedChainId*: int relatedChainId*: int
isActive*: bool isActive*: bool
isDeactivatable*: bool isDeactivatable*: bool
isNew*: bool
proc setup*(self: NetworkItem, proc setup*(self: NetworkItem,
chainId: int, chainId: int,
@ -41,7 +42,8 @@ QtObject:
isEnabled: bool, isEnabled: bool,
relatedChainId: int, relatedChainId: int,
isActive: bool, isActive: bool,
isDeactivatable: bool isDeactivatable: bool,
isNew: bool
) = ) =
self.QObject.setup self.QObject.setup
self.chainId = chainId self.chainId = chainId
@ -60,6 +62,7 @@ QtObject:
self.relatedChainId = relatedChainId self.relatedChainId = relatedChainId
self.isActive = isActive self.isActive = isActive
self.isDeactivatable = isDeactivatable self.isDeactivatable = isDeactivatable
self.isNew = isNew
proc delete*(self: NetworkItem) = proc delete*(self: NetworkItem) =
self.QObject.delete self.QObject.delete
@ -67,10 +70,12 @@ QtObject:
proc networkDtoToItem*(network: NetworkDto): NetworkItem = proc networkDtoToItem*(network: NetworkDto): NetworkItem =
new(result, delete) new(result, delete)
let rpcProviders = network.rpcProviders.map(p => rpcProviderDtoToItem(p)) let rpcProviders = network.rpcProviders.map(p => rpcProviderDtoToItem(p))
# We construct the isNew value client-side, at least for now
let isNew = network.chainId == Base or network.chainId == BaseSepolia
result.setup(network.chainId, network.layer, network.chainName, network.iconUrl, network.shortName, result.setup(network.chainId, network.layer, network.chainName, network.iconUrl, network.shortName,
network.chainColor, rpcProviders, network.chainColor, rpcProviders,
network.blockExplorerURL, network.nativeCurrencyName, network.nativeCurrencySymbol, network.nativeCurrencyDecimals, network.blockExplorerURL, network.nativeCurrencyName, network.nativeCurrencySymbol, network.nativeCurrencyDecimals,
network.isTest, network.isEnabled, network.relatedChainId, network.isActive, network.isDeactivatable) network.isTest, network.isEnabled, network.relatedChainId, network.isActive, network.isDeactivatable, isNew)
proc networkItemToDto*(network: NetworkItem): NetworkDto = proc networkItemToDto*(network: NetworkItem): NetworkDto =
result = NetworkDto( result = NetworkDto(
@ -109,7 +114,8 @@ QtObject:
isEnabled: {self.isEnabled}, isEnabled: {self.isEnabled},
relatedChainId: {self.relatedChainId}, relatedChainId: {self.relatedChainId},
isActive: {self.isActive}, isActive: {self.isActive},
isDeactivatable: {self.isDeactivatable} isDeactivatable: {self.isDeactivatable},
isNew: {self.isNew}
]""" ]"""
proc chainId*(self: NetworkItem): int {.slot.} = proc chainId*(self: NetworkItem): int {.slot.} =
@ -184,3 +190,8 @@ QtObject:
return self.isActive return self.isActive
QtProperty[bool] isActive: QtProperty[bool] isActive:
read = isActive read = isActive
proc isNew*(self: NetworkItem): bool {.slot.} =
return self.isNew
QtProperty[bool] isNew:
read = isNew

View File

@ -1,9 +1,11 @@
const Mainnet = 1 const Mainnet = 1
const Sepolia = 11155111 const Sepolia = 11155111
const Base = 8453
const BaseSepolia = 84532
const NETWORK_LAYER_1 = 1 const NETWORK_LAYER_1 = 1
const NETWORK_LAYER_2 = 2 const NETWORK_LAYER_2 = 2
export Mainnet, Sepolia export Mainnet, Sepolia, Base, BaseSepolia
export NETWORK_LAYER_1, NETWORK_LAYER_2 export NETWORK_LAYER_1, NETWORK_LAYER_2

View File

@ -51,6 +51,8 @@ SplitView {
multiSelection: multiSelectionCheckBox.checked multiSelection: multiSelectionCheckBox.checked
showTitle: ctrlShowTitle.checked showTitle: ctrlShowTitle.checked
showManageNetworksButton: ctrlShowManageNetworksButton.checked showManageNetworksButton: ctrlShowManageNetworksButton.checked
showNewTag: ctrlShowNewTagButton.checked
showNewDecorator: ctrlShowNewDecoratorButton.checked
selectionAllowed: selectionAllowedCheckBox.checked selectionAllowed: selectionAllowedCheckBox.checked
showSelectionIndicator: (ctrlShowCheckBoxes.checked && multiSelection) || (ctrlShowRadioButtons.checked && !multiSelection) showSelectionIndicator: (ctrlShowCheckBoxes.checked && multiSelection) || (ctrlShowRadioButtons.checked && !multiSelection)
} }
@ -105,6 +107,18 @@ SplitView {
checked: true checked: true
} }
CheckBox {
id: ctrlShowNewTagButton
text: "Show 'NEW' tag"
checked: true
}
CheckBox {
id: ctrlShowNewDecoratorButton
text: "Show 'New' decorator"
checked: true
}
CheckBox { CheckBox {
id: selectionAllowedCheckBox id: selectionAllowedCheckBox
text: "Selection allowed" text: "Selection allowed"

View File

@ -0,0 +1,45 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import Storybook 1.0
import utils 1.0
SplitView {
id: root
orientation: Qt.Horizontal
Item {
SplitView.fillWidth: true
SplitView.fillHeight: true
StatusNewTag {
anchors.centerIn: parent
tooltipText: ctrlTooltip.text
}
}
LogsAndControlsPanel {
SplitView.minimumWidth: 300
SplitView.preferredWidth: 400
SplitView.fillHeight: true
RowLayout {
Label {
text: "Tooltip:"
}
TextField {
id: ctrlTooltip
text: "Hic sunt leones!!!"
}
}
}
}
// category: Components
// https://www.figma.com/design/FkFClTCYKf83RJWoifWgoX/Wallet-v2?node-id=28725-330957&m=dev

View File

@ -420,6 +420,7 @@ QtObject {
isEnabled: true, isEnabled: true,
isActive: true, isActive: true,
isDeactivatable: false, isDeactivatable: false,
isNew: false,
}, },
{ {
chainId: sepMainnetChainId, chainId: sepMainnetChainId,
@ -438,6 +439,7 @@ QtObject {
isEnabled: false, isEnabled: false,
isActive: true, isActive: true,
isDeactivatable: false, isDeactivatable: false,
isNew: false,
}, },
{ {
chainId: optChainId, chainId: optChainId,
@ -456,6 +458,7 @@ QtObject {
isEnabled: true, isEnabled: true,
isActive: false, isActive: false,
isDeactivatable: true, isDeactivatable: true,
isNew: false,
}, },
{ {
chainId: sepOptChainId, chainId: sepOptChainId,
@ -474,6 +477,7 @@ QtObject {
isEnabled: true, isEnabled: true,
isActive: true, isActive: true,
isDeactivatable: true, isDeactivatable: true,
isNew: false,
}, },
{ {
chainId: arbChainId, chainId: arbChainId,
@ -492,6 +496,7 @@ QtObject {
isEnabled: false, isEnabled: false,
isActive: true, isActive: true,
isDeactivatable: true, isDeactivatable: true,
isNew: false,
}, },
{ {
chainId: sepArbChainId, chainId: sepArbChainId,
@ -510,6 +515,7 @@ QtObject {
isEnabled: false, isEnabled: false,
isActive: true, isActive: true,
isDeactivatable: true, isDeactivatable: true,
isNew: false,
}, },
{ {
chainId: baseChainId, chainId: baseChainId,
@ -528,6 +534,7 @@ QtObject {
isEnabled: false, isEnabled: false,
isActive: false, isActive: false,
isDeactivatable: true, isDeactivatable: true,
isNew: true,
}, },
{ {
chainId: sepBaseChainId, chainId: sepBaseChainId,
@ -546,6 +553,7 @@ QtObject {
isEnabled: false, isEnabled: false,
isActive: true, isActive: true,
isDeactivatable: true, isDeactivatable: true,
isNew: true,
}] }]
) )
} }

View File

@ -0,0 +1,36 @@
import QtQuick 2.15
import QtGraphicalEffects 1.15
import StatusQ 0.1
import StatusQ.Components.private 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
property int borderWidth: 2
height: innerCircle.height + borderWidth
width: innerCircle.width + borderWidth
color: Theme.palette.baseColor2
radius: height/2
Rectangle {
id: innerCircle
anchors.centerIn: parent
height: 10
width: 10
StatusGradient {
id: gradient
anchors.fill: parent
source: parent
}
radius: height/2
}
}

View File

@ -0,0 +1,46 @@
import QtQuick 2.15
import QtGraphicalEffects 1.15
import StatusQ.Components.private 0.1
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
property alias tooltipText: tip.text
property alias cursorShape: hoverHandler.cursorShape
readonly property bool hovered: hoverHandler.hovered
StatusGradient {
id: gradient
anchors.fill: parent
source: root
}
implicitHeight: 20
implicitWidth: 36
radius: height/2
border.width: 0
StatusBaseText {
font.pixelSize: 10
font.weight: Font.DemiBold
color: Theme.palette.indirectColor4
anchors.centerIn: parent
text: qsTr("NEW")
}
StatusToolTip {
id: tip
visible: hoverHandler.hovered && !!text
maxWidth: 333
}
HoverHandler {
id: hoverHandler
enabled: root.visible
}
}

View File

@ -0,0 +1,13 @@
import QtQuick 2.15
import QtGraphicalEffects 1.15
LinearGradient {
id: root
start: Qt.point(-0.48*width, 0.46*height)
end: Qt.point(1.36*width, 0.42*height)
gradient: Gradient {
GradientStop { position: 0.0; color: "#2A799B" }
GradientStop { position: 0.25; color: "#F6B03C" }
GradientStop { position: 0.84; color: "#FF33A3" }
}
}

View File

@ -4,3 +4,4 @@ StatusImageMessage 0.1 statusMessage/StatusImageMessage.qml
StatusMessageImageAlbum 0.1 statusMessage/StatusMessageImageAlbum.qml StatusMessageImageAlbum 0.1 statusMessage/StatusMessageImageAlbum.qml
StatusComboboxBackground 0.1 StatusComboboxBackground.qml StatusComboboxBackground 0.1 StatusComboboxBackground.qml
StatusComboboxIndicator 0.1 StatusComboboxIndicator.qml StatusComboboxIndicator 0.1 StatusComboboxIndicator.qml
StatusGradient 0.1 StatusGradient.qml

View File

@ -48,6 +48,8 @@ StatusMessageHeader 0.1 StatusMessageHeader.qml
StatusMessageSenderDetails 0.1 StatusMessageSenderDetails.qml StatusMessageSenderDetails 0.1 StatusMessageSenderDetails.qml
StatusNavigationListItem 0.1 StatusNavigationListItem.qml StatusNavigationListItem 0.1 StatusNavigationListItem.qml
StatusNavigationPanelHeadline 0.1 StatusNavigationPanelHeadline.qml StatusNavigationPanelHeadline 0.1 StatusNavigationPanelHeadline.qml
StatusNewDecorator 0.1 StatusNewDecorator.qml
StatusNewTag 0.1 StatusNewTag.qml
StatusOnlineBadge 0.1 StatusOnlineBadge.qml StatusOnlineBadge 0.1 StatusOnlineBadge.qml
StatusPageIndicator 0.1 StatusPageIndicator.qml StatusPageIndicator 0.1 StatusPageIndicator.qml
StatusQrCodeScanner 0.1 StatusQrCodeScanner.qml StatusQrCodeScanner 0.1 StatusQrCodeScanner.qml

View File

@ -48,6 +48,8 @@
<file>StatusQ/Components/StatusMessageSenderDetails.qml</file> <file>StatusQ/Components/StatusMessageSenderDetails.qml</file>
<file>StatusQ/Components/StatusNavigationListItem.qml</file> <file>StatusQ/Components/StatusNavigationListItem.qml</file>
<file>StatusQ/Components/StatusNavigationPanelHeadline.qml</file> <file>StatusQ/Components/StatusNavigationPanelHeadline.qml</file>
<file>StatusQ/Components/StatusNewDecorator.qml</file>
<file>StatusQ/Components/StatusNewTag.qml</file>
<file>StatusQ/Components/StatusOnlineBadge.qml</file> <file>StatusQ/Components/StatusOnlineBadge.qml</file>
<file>StatusQ/Components/StatusPageIndicator.qml</file> <file>StatusQ/Components/StatusPageIndicator.qml</file>
<file>StatusQ/Components/StatusQrCodeScanner.qml</file> <file>StatusQ/Components/StatusQrCodeScanner.qml</file>
@ -69,6 +71,7 @@
<file>StatusQ/Components/private/LoadingDotItem.qml</file> <file>StatusQ/Components/private/LoadingDotItem.qml</file>
<file>StatusQ/Components/private/StatusComboboxBackground.qml</file> <file>StatusQ/Components/private/StatusComboboxBackground.qml</file>
<file>StatusQ/Components/private/StatusComboboxIndicator.qml</file> <file>StatusQ/Components/private/StatusComboboxIndicator.qml</file>
<file>StatusQ/Components/private/StatusGradient.qml</file>
<file>StatusQ/Components/private/chart/ChartCanvas.qml</file> <file>StatusQ/Components/private/chart/ChartCanvas.qml</file>
<file>StatusQ/Components/private/chart/Library/Animator.qml</file> <file>StatusQ/Components/private/chart/Library/Animator.qml</file>
<file>StatusQ/Components/private/chart/Library/Chart.bundle.js</file> <file>StatusQ/Components/private/chart/Library/Chart.bundle.js</file>

View File

@ -33,10 +33,13 @@ StatusComboBox {
property bool showTitle: true property bool showTitle: true
property bool selectionAllowed: true property bool selectionAllowed: true
property bool showManageNetworksButton: false property bool showManageNetworksButton: false
property bool showNewTag: false
property bool showNewDecorator: false
property var selection: [] property var selection: []
signal toggleNetwork(int chainId, int index) signal toggleNetwork(int chainId, int index)
signal manageNetworksClicked() signal manageNetworksClicked()
signal popupOpened()
onSelectionChanged: { onSelectionChanged: {
if (root.selection !== networkSelectorView.selection) { if (root.selection !== networkSelectorView.selection) {
@ -44,6 +47,15 @@ StatusComboBox {
} }
} }
StatusNewDecorator {
id: newDecorator
anchors.verticalCenter: parent.top
anchors.verticalCenterOffset: 3
anchors.horizontalCenter: parent.right
anchors.horizontalCenterOffset: -3
visible: root.showNewDecorator
}
control.padding: 12 control.padding: 12
control.spacing: 0 control.spacing: 0
control.rightPadding: 36 control.rightPadding: 36
@ -154,6 +166,7 @@ StatusComboBox {
multiSelection: root.multiSelection multiSelection: root.multiSelection
showSelectionIndicator: root.showSelectionIndicator showSelectionIndicator: root.showSelectionIndicator
showManageNetworksButton: root.showManageNetworksButton showManageNetworksButton: root.showManageNetworksButton
showNewTag: root.showNewTag
selection: root.selection selection: root.selection
onSelectionChanged: { onSelectionChanged: {
@ -168,6 +181,8 @@ StatusComboBox {
control.popup.close() control.popup.close()
root.manageNetworksClicked() root.manageNetworksClicked()
} }
onOpened: root.popupOpened()
} }
Connections { Connections {

View File

@ -1,8 +1,10 @@
import QtQuick 2.15 import QtQuick 2.15
import QtQml 2.15 import QtQml 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15 import QtGraphicalEffects 1.15
import StatusQ 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
@ -24,6 +26,7 @@ StatusListItem {
property bool showIndicator: true property bool showIndicator: true
property bool multiSelection: false property bool multiSelection: false
property bool interactive: true property bool interactive: true
property bool showNewTag: false
// output signal // output signal
// Emitted when the checkbox is clicked // Emitted when the checkbox is clicked
@ -40,6 +43,8 @@ StatusListItem {
d.toggled() d.toggled()
} }
statusListItemTitleIcons.sourceComponent: root.showNewTag ? newTagComponent : undefined
leftPadding: 16 leftPadding: 16
rightPadding: 16 rightPadding: 16
statusListItemTitleArea.anchors.leftMargin: 12 statusListItemTitleArea.anchors.leftMargin: 12
@ -98,6 +103,19 @@ StatusListItem {
} }
} }
Component {
id: newTagComponent
RowLayout {
spacing: 0
Column {
width: 8
}
StatusNewTag {
tooltipText: qsTr("%1 chain integrated. You can now view and swap %1 assets, as well as interact with %1 dApps.").arg(root.title)
}
}
}
QtObject { QtObject {
id: d id: d
property int checkState: root.checkState property int checkState: root.checkState

View File

@ -2,6 +2,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQml 2.15 import QtQml 2.15
import Qt.labs.settings 1.1
import StatusQ 0.1 import StatusQ 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
@ -45,6 +46,11 @@ Item {
implicitHeight: 88 implicitHeight: 88
Settings {
id: walletHeaderLocalSettings
property bool networksFilterOpened: false
}
GridLayout { GridLayout {
width: parent.width width: parent.width
columns: 2 columns: 2
@ -180,12 +186,15 @@ Item {
id: networkFilter id: networkFilter
showTitle: false showTitle: false
showManageNetworksButton: true showManageNetworksButton: true
showNewTag: true
showNewDecorator: !walletHeaderLocalSettings.networksFilterOpened
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
flatNetworks: root.walletStore.filteredFlatModel flatNetworks: root.walletStore.filteredFlatModel
onToggleNetwork: root.walletStore.toggleNetwork(chainId) onToggleNetwork: root.walletStore.toggleNetwork(chainId)
onManageNetworksClicked: root.manageNetworksRequested() onManageNetworksClicked: root.manageNetworksRequested()
onPopupOpened: walletHeaderLocalSettings.networksFilterOpened = true
Binding on selection { Binding on selection {
value: chainIdsAggregator.value value: chainIdsAggregator.value

View File

@ -24,6 +24,7 @@ Popup {
property bool selectionAllowed: true property bool selectionAllowed: true
property bool multiSelection: false property bool multiSelection: false
property bool showManageNetworksButton: false property bool showManageNetworksButton: false
property bool showNewTag: false
property var selection: [] property var selection: []
signal toggleNetwork(int chainId, int index) signal toggleNetwork(int chainId, int index)
@ -68,6 +69,7 @@ Popup {
interactive: root.selectionAllowed interactive: root.selectionAllowed
multiSelection: root.multiSelection multiSelection: root.multiSelection
showIndicator: root.showSelectionIndicator showIndicator: root.showSelectionIndicator
showNewTag: root.showNewTag
selection: root.selection selection: root.selection
onSelectionChanged: { onSelectionChanged: {

View File

@ -26,6 +26,7 @@ StatusListView {
property bool showIndicator: true property bool showIndicator: true
property bool multiSelection: false property bool multiSelection: false
property bool interactive: true property bool interactive: true
property bool showNewTag: true
/** /**
The list selected of chain ids The list selected of chain ids
@ -62,6 +63,7 @@ StatusListView {
showIndicator: root.showIndicator showIndicator: root.showIndicator
multiSelection: root.multiSelection multiSelection: root.multiSelection
interactive: root.interactive interactive: root.interactive
showNewTag: root.showNewTag && model.isNew
checkState: inSelection ? (d.allSelected && root.interactive ? Qt.PartiallyChecked : Qt.Checked) : Qt.Unchecked checkState: inSelection ? (d.allSelected && root.interactive ? Qt.PartiallyChecked : Qt.Checked) : Qt.Unchecked
nextCheckState: checkState nextCheckState: checkState

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit d6a67cb18206e4937c69411c2b4f151b784a04f4 Subproject commit 86fa8950c3e308e1f026574cfd5bf12458def833