diff --git a/ui/StatusQ/sandbox/controls/Others.qml b/ui/StatusQ/sandbox/controls/Others.qml index 9e57f8e956..e2136e38c5 100644 --- a/ui/StatusQ/sandbox/controls/Others.qml +++ b/ui/StatusQ/sandbox/controls/Others.qml @@ -52,7 +52,7 @@ ColumnLayout { model: 12 StatusLetterIdenticon { name: "A" - color: Theme.palette.userCustomizationColors[index] + letterIdenticonColor: Theme.palette.userCustomizationColors[index] letterSize: 16 } } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml index 852a6367a4..91dfd27a94 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml @@ -394,7 +394,7 @@ ItemDelegate { height: root.icon.height emoji: root.hasEmoji ? root.icon.name : "" name: !root.hasEmoji ? root.icon.name : "" - color: root.icon.color + letterIdenticonColor: root.icon.color } } } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusLetterIdenticon.qml b/ui/StatusQ/src/StatusQ/Components/StatusLetterIdenticon.qml index 1c04fd28ba..fedbcec15a 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusLetterIdenticon.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusLetterIdenticon.qml @@ -12,8 +12,16 @@ Rectangle { property string emojiSize: Emoji.size.small property int letterSize: 21 property int charactersLen: 1 + property color letterIdenticonColor: Theme.palette.miscColor5 + property bool useAcronymForLetterIdenticon: false + + color: { + if (root.useAcronymForLetterIdenticon) { + return Qt.rgba(root.letterIdenticonColor.r, root.letterIdenticonColor.g, root.letterIdenticonColor.b, 0.2) + } + return root.letterIdenticonColor + } - color: Theme.palette.miscColor5 width: 40 height: 40 radius: width / 2 @@ -38,9 +46,30 @@ Rectangle { font.weight: Font.Bold font.pixelSize: root.letterSize - color: d.luminance(root.color) > 0.5 ? Qt.rgba(0, 0, 0, 0.5) : Qt.rgba(1, 1, 1, 0.7) + color: { + if (root.useAcronymForLetterIdenticon) { + return root.letterIdenticonColor + } + return d.luminance(root.letterIdenticonColor) > 0.5 ? Qt.rgba(0, 0, 0, 0.5) : Qt.rgba(1, 1, 1, 0.7) + } text: { + let parts = root.name.split(" ") + if (root.useAcronymForLetterIdenticon && parts.length > 1) { + let word = "" + for (let i=0; i= parts.length) { + return word + } + + let shift = (parts[i].charAt(0) === "#") || + (parts[i].charAt(0) === "@") + + word += parts[i].substring(shift, shift + 1).toUpperCase() + } + return word + } + const shift = (root.name.charAt(0) === "#") || (root.name.charAt(0) === "@") return root.name.substring(shift, shift + charactersLen).toUpperCase() diff --git a/ui/StatusQ/src/StatusQ/Components/StatusListItemBadge.qml b/ui/StatusQ/src/StatusQ/Components/StatusListItemBadge.qml index bc536008c6..8a1fd0d272 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusListItemBadge.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusListItemBadge.qml @@ -50,7 +50,7 @@ Control { implicitHeight: root.asset.width letterSize: 11 visible: root.asset.isLetterIdenticon - color: root.asset.color + letterIdenticonColor: root.asset.color name: root.primaryText emoji: root.asset.emoji emojiSize: root.asset.emojiSize diff --git a/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml b/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml index 1471c8da10..7b80c48918 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml @@ -109,12 +109,13 @@ Loader { objectName: "statusSmartIdenticonLetter" width: root.asset.width height: root.asset.height - color: root.asset.color + letterIdenticonColor: root.asset.color name: root.name emoji: root.asset.emoji emojiSize: root.asset.emojiSize letterSize: root.asset.letterSize charactersLen: root.asset.charactersLen + useAcronymForLetterIdenticon: root.asset.useAcronymForLetterIdenticon } } diff --git a/ui/StatusQ/src/StatusQ/Core/StatusAssetSettings.qml b/ui/StatusQ/src/StatusQ/Core/StatusAssetSettings.qml index b00dd55ce7..9e6c632ee1 100644 --- a/ui/StatusQ/src/StatusQ/Core/StatusAssetSettings.qml +++ b/ui/StatusQ/src/StatusQ/Core/StatusAssetSettings.qml @@ -14,6 +14,7 @@ QtObject { property color disabledColor property int rotation property bool isLetterIdenticon + property bool useAcronymForLetterIdenticon property int letterSize: emoji ? 11 : (charactersLen == 1 ? _oneLetterSize : _twoLettersSize) property int charactersLen: 1 property string emoji diff --git a/ui/StatusQ/src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml b/ui/StatusQ/src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml index c559cf9fc9..42c2067b8a 100644 --- a/ui/StatusQ/src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml +++ b/ui/StatusQ/src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml @@ -45,7 +45,7 @@ Row { StatusLetterIdenticon { width: statusImageWithTitle.asset.width height: statusImageWithTitle.asset.height - color: statusImageWithTitle.asset.bgColor + letterIdenticonColor: statusImageWithTitle.asset.bgColor name: statusImageWithTitle.title } } diff --git a/ui/app/AppLayouts/Browser/controls/BookmarkButton.qml b/ui/app/AppLayouts/Browser/controls/BookmarkButton.qml index e8bf94f292..4b78285986 100644 --- a/ui/app/AppLayouts/Browser/controls/BookmarkButton.qml +++ b/ui/app/AppLayouts/Browser/controls/BookmarkButton.qml @@ -41,7 +41,7 @@ Item { StatusQ.StatusLetterIdenticon { id: identicon anchors.horizontalCenter: parent.horizontalCenter - color: Theme.palette.baseColor2 + letterIdenticonColor: Theme.palette.baseColor2 identiconText.text: text.charAt(0) identiconText.color: Theme.palette.baseColor1 visible: !bookmarkImage.visible && !addButton.visible diff --git a/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml b/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml index 41758153f8..d5cc9dc9a6 100644 --- a/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml +++ b/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml @@ -27,7 +27,6 @@ StatusListItem { property bool favourite: false property bool areTestNetworksEnabled: false property bool isSepoliaEnabled: false - property var saveAddress: function (name, address, favourite, chainShortNames, ens) {} signal openSendModal(string recipient) @@ -38,24 +37,36 @@ StatusListItem { subTitle: { if (ens.length > 0) return ens - else - return WalletUtils.colorizedChainPrefix(chainShortNames) + address + else { + return sensor.containsMouse ? WalletUtils.colorizedChainPrefix(root.chainShortNames) + + Utils.richColorText(root.address, Theme.palette.directColor1) + : root.chainShortNames + root.address + } } + border.color: Theme.palette.baseColor5 - asset.name: d.favouriteEnabled ? (root.favourite ? "star-icon" : "favourite") : "" - asset.color: root.favourite ? Theme.palette.pinColor1 : (showButtons ? Theme.palette.directColor1 : Theme.palette.baseColor1) // star icon color default - asset.hoverColor: root.favourite ? "transparent": Theme.palette.directColor1 // star icon color on hover - asset.bgColor: statusListItemIcon.hovered ? Theme.palette.primaryColor3 : "transparent" // icon outer background color - asset.bgRadius: 8 + + asset { + width: 40 + height: 40 + color: Utils.getColorForId(root.colorId) + charactersLen: { + let parts = root.name.split(" ") + if (parts.length > 1) { + return 2 + } + return 1 + } + isLetterIdenticon: true + useAcronymForLetterIdenticon: true + } statusListItemIcon.hoverEnabled: true - onIconClicked: { - root.saveAddress(root.name, root.address, !root.favourite, root.chainShortNames, root.ens) + onClicked: { + root.openSendModal(d.visibleAddress) } - statusListItemSubTitle.font.pixelSize: 13 - statusListItemSubTitle.customColor: !enabled ? Theme.palette.baseColor1 : Theme.palette.directColor1 statusListItemComponentsSlot.spacing: 0 property bool showButtons: sensor.containsMouse @@ -67,13 +78,6 @@ StatusListItem { } components: [ - StatusRoundButton { - icon.color: root.showButtons ? Theme.palette.directColor1 : Theme.palette.baseColor1 - type: StatusRoundButton.Type.Quinary - radius: 8 - icon.name: "send" - onClicked: openSendModal(d.visibleAddress) - }, StatusRoundButton { objectName: "savedAddressView_Delegate_menuButton_" + root.name visible: !!root.name @@ -94,19 +98,6 @@ StatusListItem { ); } - }, - StatusRoundButton { - visible: !root.name - icon.color: root.showButtons ? Theme.palette.directColor1 : Theme.palette.baseColor1 - type: StatusRoundButton.Type.Tertiary - icon.name: "add" - onClicked: { - Global.openAddEditSavedAddressesPopup({ - addAddress: true, - address: d.visibleAddress, - ens: root.ens - }) - } } ] @@ -140,7 +131,7 @@ StatusListItem { contactEns = "" } StatusAction { - text: qsTr("Edit") + text: qsTr("Edit saved address") objectName: "editroot" assetSettings.name: "pencil-outline" onTriggered: { @@ -156,7 +147,7 @@ StatusListItem { } } StatusAction { - text: qsTr("Copy") + text: qsTr("Copy address") objectName: "copySavedAddressAction" assetSettings.name: "copy" onTriggered: { @@ -166,6 +157,14 @@ StatusListItem { store.copyToClipboard(root.ens) } } + StatusAction { + text: qsTr("Show address QR") + objectName: "showQrSavedAddressAction" + assetSettings.name: "qr" + onTriggered: { + console.warn("TODO: open qr popup...") + } + } StatusMenuSeparator { } StatusAction { @@ -211,7 +210,7 @@ StatusListItem { } StatusMenuSeparator { } StatusAction { - text: qsTr("Delete") + text: qsTr("Remove saved address") type: StatusAction.Type.Danger assetSettings.name: "delete" objectName: "deleteSavedAddress" diff --git a/ui/app/AppLayouts/Wallet/popups/AddEditSavedAddressPopup.qml b/ui/app/AppLayouts/Wallet/popups/AddEditSavedAddressPopup.qml index 3427070f28..2d31489e72 100644 --- a/ui/app/AppLayouts/Wallet/popups/AddEditSavedAddressPopup.qml +++ b/ui/app/AppLayouts/Wallet/popups/AddEditSavedAddressPopup.qml @@ -113,6 +113,16 @@ StatusDialog { d.chainShortNames = "" allNetworksModelCopy.setEnabledNetworks([]) } + + function submit(event) { + if (!d.valid + || !d.dirty + || event !== undefined && event.key !== Qt.Key_Return && event.key !== Qt.Key_Enter) + return + + RootStore.createOrUpdateSavedAddress(d.name, d.address, d.ens, d.colorId, d.favourite, d.chainShortNames) + root.close() + } } Column { @@ -155,6 +165,10 @@ StatusDialog { ] input.clearable: true input.rightPadding: 16 + + onKeyPressed: { + d.submit(event) + } } StatusInput { @@ -234,6 +248,10 @@ StatusDialog { } } + onKeyPressed: { + d.submit(event) + } + property bool skipTextUpdate: false function setPlainText(newText) { @@ -395,8 +413,7 @@ StatusDialog { text: d.editMode? qsTr("Save") : qsTr("Add address") enabled: d.valid && d.dirty onClicked: { - RootStore.createOrUpdateSavedAddress(d.name, d.address, d.ens, d.colorId, d.favourite, d.chainShortNames) - root.close() + d.submit() } objectName: "addSavedAddress" } diff --git a/ui/app/AppLayouts/Wallet/views/SavedAddresses.qml b/ui/app/AppLayouts/Wallet/views/SavedAddresses.qml index 02c7f75821..ddefbfa61c 100644 --- a/ui/app/AppLayouts/Wallet/views/SavedAddresses.qml +++ b/ui/app/AppLayouts/Wallet/views/SavedAddresses.qml @@ -47,17 +47,40 @@ ColumnLayout { Layout.fillHeight: true } + SearchBox { + Layout.fillWidth: true + visible: listView.visible + placeholderText: qsTr("Search for name, ENS or address") + } + StatusListView { id: listView objectName: "SavedAddressesView_savedAddresses" Layout.fillWidth: true Layout.fillHeight: true - spacing: 5 + Layout.topMargin: 16 + spacing: 8 visible: count > 0 + model: SortFilterProxyModel { sourceModel: RootStore.savedAddresses - sorters: RoleSorter { roleName: "createdAt"; sortOrder: Qt.DescendingOrder } + sorters: RoleSorter { roleName: "name"; sortOrder: Qt.AscendingOrder } } + + section.property: "name" + section.criteria: ViewSection.FirstCharacter + section.delegate: Item { + height: 34 + width: children.width + StatusBaseText { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + text: section.toUpperCase() + color: Theme.palette.baseColor1 + font.pixelSize: 15 + } + } + delegate: SavedAddressesDelegate { id: savedAddressDelegate objectName: "savedAddressView_Delegate_" + name