From 259aeba066c4400650b357af3fc9b790a6584d0b Mon Sep 17 00:00:00 2001 From: Noelia Date: Tue, 31 May 2022 17:18:28 +0200 Subject: [PATCH] feat(StatusTagSelector): Introduced readonly tags and possibility of icon - Different tag color depending if the entry `isReadonly` or not. - Tag disabled if the entry `isReadonly`. - Possibility to show icon if entry contains the proper info. - Added property `orderByReadonly` to position `isReadonly` entries in the left. Updated sandbox project examples according to new tag updates. Closes #694 --- ui/StatusQ/sandbox/controls/Layout.qml | 4 + ui/StatusQ/sandbox/demoapp/data/Models.qml | 4 + .../sandbox/pages/StatusTagSelectorPage.qml | 16 ++- .../StatusQ/Components/StatusTagSelector.qml | 119 ++++++++++++++---- 4 files changed, 115 insertions(+), 28 deletions(-) diff --git a/ui/StatusQ/sandbox/controls/Layout.qml b/ui/StatusQ/sandbox/controls/Layout.qml index f75dbde255..6b5c28599a 100644 --- a/ui/StatusQ/sandbox/controls/Layout.qml +++ b/ui/StatusQ/sandbox/controls/Layout.qml @@ -83,6 +83,8 @@ Column { icon: "" isIdenticon: false onlineStatus: 3 + isReadonly: true + tagIcon: "crown" } ListElement { publicId: "0x1" @@ -90,6 +92,8 @@ Column { icon: "" isIdenticon: false onlineStatus: 1 + isReadonly: false + tagIcon: "" } } toLabelText: qsTr("To: ") diff --git a/ui/StatusQ/sandbox/demoapp/data/Models.qml b/ui/StatusQ/sandbox/demoapp/data/Models.qml index 8d9ce0b672..34d360d1ad 100644 --- a/ui/StatusQ/sandbox/demoapp/data/Models.qml +++ b/ui/StatusQ/sandbox/demoapp/data/Models.qml @@ -852,6 +852,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/ nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" isIdenticon: true + isAdmin: false ringSpecModel: [ ListElement {colorId: 13; segmentLength: 5}, ListElement {colorId: 31; segmentLength: 5}, ListElement {colorId: 10; segmentLength: 1}, @@ -868,6 +869,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I isMutualContact: false onlineStatus: false icon: "" + isAdmin: false isIdenticon: false } ListElement { @@ -877,6 +879,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I trustIndicator: StatusContactVerificationIcons.TrustedType.None isMutualContact: false onlineStatus: true + isAdmin: false icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDK ExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg==" isIdenticon: true @@ -897,6 +900,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I onlineStatus: false icon: "" isIdenticon: false + isAdmin: false ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1}, ListElement {colorId: 28; segmentLength: 1}, ListElement {colorId: 31; segmentLength: 1}, diff --git a/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml b/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml index 6afbb4bb74..3b778d2ceb 100644 --- a/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml +++ b/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml @@ -9,17 +9,21 @@ Item { property ListModel asortedContacts: ListModel { ListElement { publicId: "0x0" - name: "Maria" + name: "emily.eth" icon: "" isIdenticon: false onlineStatus: 3 + isReadonly: false + tagIcon: "" } ListElement { publicId: "0x1" - name: "James" + name: "vitalikbuterin" icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" isIdenticon: false onlineStatus: 1 + isReadonly: false + tagIcon: "" } ListElement { publicId: "0x2" @@ -27,13 +31,17 @@ Item { icon: "" isIdenticon: false onlineStatus: 2 + isReadonly: false + tagIcon: "" } ListElement { publicId: "0x3" - name: "Tracy" + name: "carmen.eth" icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" isIdenticon: true onlineStatus: 3 + isReadonly: true + tagIcon: "crown" } ListElement { publicId: "0x4" @@ -41,6 +49,8 @@ Item { icon: "" isIdenticon: false onlineStatus: 3 + isReadonly: false + tagIcon: "" } } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml b/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml index f53a726062..1ca844253f 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml @@ -132,6 +132,12 @@ Item { By default is set to false. */ property bool showSortedListOnlyWhenText: false + /*! + \qmlproperty bool StatusTagSelector::orderByReadonly + This property will decide if the displayed tag names will be ordered from left to right starting with the items that are marked as `isReadonly`. + By default is set to true (readonly names at left). + */ + property bool orderByReadonly: true /*! \qmlmethod @@ -146,9 +152,12 @@ Item { \qmlmethod This function is used to insert a new tag. */ - function insertTag(name, id) { + function insertTag(name, id, isReadonly, tagIcon) { if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) { - namesModel.insert(namesModel.count, {"name": name, "publicId": id}); + if(orderByReadonly && isReadonly) + namesModel.insert(0, {"name": name, "publicId": id, "isReadonly": !!isReadonly, "tagIcon": tagIcon ? tagIcon : ""}); + else + namesModel.insert(namesModel.count, {"name": name, "publicId": id, "isReadonly": !!isReadonly, "tagIcon": tagIcon ? tagIcon : ""}); addMember(id); edit.clear(); } @@ -165,11 +174,17 @@ Item { var entry = inputModel.get(i); if (entry.name.toLowerCase().includes(text.toLowerCase()) && !find(namesModel, function(item) { return item.name === entry.name })) { - sortedList.append({"publicId": entry.publicId, "name": entry.name, - "nickName": entry.nickName, "trustIndicator": entry.trustIndicator, - "isMutualContact": entry.isMutualContact, "ringSpecModel": entry.ringSpecModel, - "icon": entry.icon, "isIdenticon": entry.isIdenticon, - "onlineStatus": entry.onlineStatus}); + sortedList.append({"publicId": entry.publicId, + "name": entry.name, + "nickName": entry.nickName, + "trustIndicator": entry.trustIndicator, + "isMutualContact": entry.isMutualContact, + "ringSpecModel": entry.ringSpecModel, + "icon": entry.icon, + "isIdenticon": entry.isIdenticon, + "onlineStatus": entry.onlineStatus, + "tagIcon": entry.tagIcon ? entry.tagIcon : "", + "isReadonly": !!entry.isReadonly}); userListView.model = sortedList; } } @@ -198,11 +213,28 @@ Item { 2 * bgRect.anchors.margins + userListView.anchors.topMargin + userListView.anchors.bottomMargin + (userListView.model.count * 64): 0 + + function orderNamesModel() { + if(root.orderByReadonly) { + for(var i = 0; i < namesModel.count; i++) { + var entry = namesModel.get(i) + if(entry.isReadonly) { + namesModel.move(i, 0, 1) + } + } + } + } } implicitWidth: 448 implicitHeight: (tagSelectorRect.height + d.suggestionContainerHeight) > root.maxHeight ? root.maxHeight : (tagSelectorRect.height + d.suggestionContainerHeight) + onOrderByReadonlyChanged: { d.orderNamesModel() } + Component.onCompleted: { + // Component initialization: + d.orderNamesModel() + } + Rectangle { id: tagSelectorRect width: parent.width @@ -247,29 +279,63 @@ Item { onCountChanged: { scrollToEnd(); } delegate: Rectangle { id: nameDelegate - width: (nameText.contentWidth + 34) + + property int tagMargins: 8 + property int tagIconsSize: 20 + function getTagColor(isReadonly) { + if(isReadonly) { + return Theme.palette.baseColor1 + } + else { + return mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1 + } + } + + width: tagRow.implicitWidth + 2 * nameDelegate.tagMargins height: 30 - color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1 + color: getTagColor(model.isReadonly) radius: 8 - StatusBaseText { - id: nameText + Row { + id: tagRow + height: parent.height anchors.left: parent.left - anchors.leftMargin: 8 - anchors.verticalCenter: parent.verticalCenter - color: Theme.palette.indirectColor1 - text: name - } - StatusIcon { - anchors.left: nameText.right - anchors.verticalCenter: parent.verticalCenter - color: Theme.palette.indirectColor1 - icon: "close" + anchors.leftMargin: nameDelegate.tagMargins + anchors.rightMargin: nameDelegate.tagMargins + spacing: 2 + + StatusIcon { + visible: model.tagIcon + anchors.verticalCenter: parent.verticalCenter + color: Theme.palette.indirectColor1 + width: model.tagIcon ? nameDelegate.tagIconsSize : 0 + height: nameDelegate.tagIconsSize + icon: model.tagIcon + } + StatusBaseText { + id: nameText + anchors.verticalCenter: parent.verticalCenter + color: Theme.palette.indirectColor1 + font.pixelSize: 15 + text: name + } + StatusIcon { + id: closeIcon + visible: !model.isReadonly + anchors.leftMargin: nameDelegate.tagMargins + anchors.verticalCenter: parent.verticalCenter + color: Theme.palette.indirectColor1 + width: nameDelegate.tagIconsSize + height: nameDelegate.tagIconsSize + icon: "close" + } } + MouseArea { id: mouseArea + enabled: !model.isReadonly anchors.fill: parent hoverEnabled: true - cursorShape: Qt.PointingHandCursor + cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: { removeMember(publicId); namesModel.remove(index, 1); @@ -299,8 +365,11 @@ Item { namesModel.remove((namesList.count-1), 1); } if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (sortedList.count > 0)) { - root.insertTag(sortedList.get(userListView.currentIndex).name, sortedList.get(userListView.currentIndex).publicId); - } + root.insertTag(sortedList.get(userListView.currentIndex).name, + sortedList.get(userListView.currentIndex).publicId, + sortedList.get(userListView.currentIndex).isReadonly, + sortedList.get(userListView.currentIndex).tagIcon); + } } Keys.onUpPressed: { userListView.decrementCurrentIndex(); } Keys.onDownPressed: { userListView.incrementCurrentIndex(); } @@ -405,7 +474,7 @@ Item { ringSettings.ringSpecModel: root.ringSpecModelGetter(publicId) color: (sensor.containsMouse || highlighted) ? Theme.palette.baseColor2 : "transparent" onClicked: { - root.insertTag(model.name, model.publicId); + root.insertTag(model.name, model.publicId, model.isAdmin, model.isAdmin ? "crown" : ""); } } }