From 08aced147f515982ae54a2c36503bc6fff17eec4 Mon Sep 17 00:00:00 2001 From: Alexandra Betouni <31625338+alexandraB99@users.noreply.github.com> Date: Thu, 20 Jan 2022 00:33:29 +0200 Subject: [PATCH] feat(StatusQ.Components): Adding StatusTagSelector component Added StatusTagSelector component needed for creating new chat channels, either ono on one or group based on updated designs on Figma Also added corresponding page in API Documentation Closes #526 --- .../sandbox/demoapp/ChatChannelView.qml | 103 ++++++++ ui/StatusQ/sandbox/demoapp/CreateChatView.qml | 232 ++++++++++++++++++ .../sandbox/demoapp/StatusAppChatView.qml | 225 +++-------------- ui/StatusQ/sandbox/demoapp/data/Models.qml | 52 ++++ ui/StatusQ/sandbox/main.qml | 5 + .../sandbox/pages/StatusTagSelectorPage.qml | 56 +++++ .../StatusQ/Components/StatusTagSelector.qml | 126 ++++++++++ ui/StatusQ/src/StatusQ/Components/qmldir | 1 + ui/StatusQ/statusq.qrc | 1 + 9 files changed, 613 insertions(+), 188 deletions(-) create mode 100644 ui/StatusQ/sandbox/demoapp/ChatChannelView.qml create mode 100644 ui/StatusQ/sandbox/demoapp/CreateChatView.qml create mode 100644 ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml create mode 100644 ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml diff --git a/ui/StatusQ/sandbox/demoapp/ChatChannelView.qml b/ui/StatusQ/sandbox/demoapp/ChatChannelView.qml new file mode 100644 index 0000000000..25f41203cd --- /dev/null +++ b/ui/StatusQ/sandbox/demoapp/ChatChannelView.qml @@ -0,0 +1,103 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import QtQml.Models 2.2 + +import StatusQ.Controls 0.1 +import StatusQ.Popups 0.1 +import StatusQ.Components 0.1 +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 + +ListView { + id: messageList + anchors.fill: parent + anchors.margins: 15 + clip: true + delegate: StatusMessage { + id: delegate + width: parent.width + + audioMessageInfoText: "Audio Message" + cancelButtonText: "Cancel" + saveButtonText: "Save" + loadingImageText: "Loading image..." + errorLoadingImageText: "Error loading the image" + resendText: "Resend" + pinnedMsgInfoText: "Pinned by" + + messageDetails: StatusMessageDetails { + contentType: model.contentType + messageContent: model.messageContent + amISender: model.amIsender + displayName: model.userName + secondaryName: model.localName !== "" && model.ensName.startsWith("@") ? model.ensName: "" + chatID: model.chatKey + profileImage: StatusImageSettings { + width: 40 + height: 40 + source: model.profileImage + isIdenticon: model.isIdenticon + } + messageText: model.message + hasMention: model.hasMention + contactType: model.contactType + isPinned: model.isPinned + pinnedBy: model.pinnedBy + hasExpired: model.hasExpired + } + timestamp.text: "10:00 am" + timestamp.tooltip.text: "10:01 am" + // reply related data + isAReply: model.isReply + replyDetails: StatusMessageDetails { + amISender: model.isReply ? model.replyAmISender : "" + displayName: model.isReply ? model.replySenderName: "" + profileImage: StatusImageSettings { + width: 20 + height: 20 + source: model.isReply ? model.replyProfileImage: "" + isIdenticon: model.isReply ? model.replyIsIdenticon: "" + } + messageText: model.isReply ? model.replyMessageText: "" + contentType: model.replyContentType + messageContent: model.replyMessageContent + } + quickActions: [ + StatusFlatRoundButton { + id: emojiBtn + width: 32 + height: 32 + icon.name: "reaction-b" + type: StatusFlatRoundButton.Type.Tertiary + tooltip.text: "Add reaction" + }, + StatusFlatRoundButton { + id: replyBtn + width: 32 + height: 32 + icon.name: "reply" + type: StatusFlatRoundButton.Type.Tertiary + tooltip.text: "Reply" + }, + StatusFlatRoundButton { + width: 32 + height: 32 + icon.name: "tiny/edit" + type: StatusFlatRoundButton.Type.Tertiary + tooltip.text: "Edit" + onClicked: { + delegate.editMode = !delegate.editMode + } + }, + StatusFlatRoundButton { + id: otherBtn + width: 32 + height: 32 + icon.name: "more" + type: StatusFlatRoundButton.Type.Tertiary + tooltip.text: "More" + } + ] + } +} diff --git a/ui/StatusQ/sandbox/demoapp/CreateChatView.qml b/ui/StatusQ/sandbox/demoapp/CreateChatView.qml new file mode 100644 index 0000000000..b8de5912e5 --- /dev/null +++ b/ui/StatusQ/sandbox/demoapp/CreateChatView.qml @@ -0,0 +1,232 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import QtQml.Models 2.2 +import QtGraphicalEffects 1.0 + +import StatusQ.Controls 0.1 +import StatusQ.Components 0.1 +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 + +Page { + id: root + anchors.fill: parent + anchors.margins: 16 + property ListModel contactsModel: null + background: null + + header: RowLayout { + id: headerRow + width: parent.width + height: tagSelector.height + anchors.right: parent.right + anchors.rightMargin: 8 + + StatusTagSelector { + id: tagSelector + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.leftMargin: 17 + implicitHeight: 44 + toLabelText: qsTr("To: ") + warningText: qsTr("5 USER LIMIT REACHED") + //simulate model filtering, TODO this + //makes more sense to be provided by the backend + //figure how real implementation should look like + property ListModel sortedList: ListModel { } + onTextChanged: { + sortedList.clear(); + if (text !== "") { + for (var i = 0; i < contactsModel.count; i++ ) { + var entry = contactsModel.get(i); + if (entry.name.toLowerCase().includes(text.toLowerCase())) { + sortedList.insert(sortedList.count, {"publicId": entry.publicId, "name": entry.name, + "icon": entry.icon, "isIdenticon": entry.isIdenticon, + "onlineStatus": entry.onlineStatus}); + userListView.model = sortedList; + } + } + } else { + userListView.model = contactsModel; + } + } + } + + StatusButton { + implicitHeight: 44 + enabled: (tagSelector.namesModel.count > 0) + text: "Confirm" + } + } + + contentItem: Item { + anchors.fill: parent + anchors.topMargin: headerRow.height + 16 + + Item { + anchors.fill: parent + visible: (contactsModel.count > 0) + + StatusBaseText { + id: contactsLabel + font.pixelSize: 15 + color: Theme.palette.baseColor1 + text: "Contacts" + } + Control { + width: 360 + anchors { + top: contactsLabel.bottom + topMargin: 8//Style.current.padding + bottom: parent.bottom + bottomMargin: 20//Style.current.bigPadding + } + background: Rectangle { + id: statusPopupMenuBackgroundContent + anchors.left: parent.left + anchors.right: parent.right + height: (userListView.height + 8) + visible: (tagSelector.sortedList.count > 0) + color: Theme.palette.statusPopupMenu.backgroundColor + radius: 8 + layer.enabled: true + layer.effect: DropShadow { + width: statusPopupMenuBackgroundContent.width + height: statusPopupMenuBackgroundContent.height + x: statusPopupMenuBackgroundContent.x + visible: statusPopupMenuBackgroundContent.visible + source: statusPopupMenuBackgroundContent + horizontalOffset: 0 + verticalOffset: 4 + radius: 12 + samples: 25 + spread: 0.2 + color: Theme.palette.dropShadow + } + } + contentItem: ListView { + id: userListView + anchors.left: parent.left + anchors.right: parent.right + height: (count * 64) > parent.height ? parent.height : (count * 64) + clip: true + model: contactsModel + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AsNeeded + } + boundsBehavior: Flickable.StopAtBounds + delegate: Item { + id: wrapper + anchors.right: parent.right + anchors.left: parent.left + height: 64 + property bool hovered: false + Rectangle { + id: rectangle + anchors.fill: parent + anchors.topMargin: 8 + anchors.rightMargin: 8 + anchors.leftMargin: 8 + radius: 8 + visible: (tagSelector.sortedList.count > 0) + color: (wrapper.hovered) ? Theme.palette.baseColor2 : "transparent" + } + + StatusSmartIdenticon { + id: contactImage + anchors.left: parent.left + anchors.leftMargin: 16//Style.current.padding + anchors.verticalCenter: parent.verticalCenter + name: model.name + icon: StatusIconSettings { + width: 28 + height: 28 + letterSize: 15 + } + image: StatusImageSettings { + width: 28 + height: 28 + source: model.icon + isIdenticon: model.isIdenticon + } + } + + StatusBaseText { + id: contactInfo + text: model.name + anchors.right: parent.right + anchors.rightMargin: 8 + anchors.left: contactImage.right + anchors.leftMargin: 16 + anchors.verticalCenter: parent.verticalCenter + elide: Text.ElideRight + color: Theme.palette.directColor1 + font.weight: Font.Medium + font.pixelSize: 15 + } + + StatusBadge { + id: statusBadge + width: 15 + height: 15 + anchors.left: contactImage.right + anchors.leftMargin: -8 + anchors.bottom: contactImage.bottom + border.width: 3 + border.color: Theme.palette.statusAppNavBar.backgroundColor + color: { + if (model.onlineStatus === 1) + return Theme.palette.successColor1; + else if (model.onlineStatus === 2) + return Theme.palette.pinColor1; + else if (model.onlineStatus === 3) + return Theme.palette.dangerColor1; + + return "transparent" + } + } + + MouseArea { + cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton + anchors.fill: parent + hoverEnabled: true + onEntered: { + wrapper.hovered = true; + } + onExited: { + wrapper.hovered = false; + } + onClicked: { + tagSelector.insertTag(model.name, model.publicId); + } + } + } + } + } + Component.onCompleted: { + if (visible) { + tagSelector.textEdit.forceActiveFocus(); + } + } + } + + StatusBaseText { + visible: (contactsModel.count === 0) + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: 15 + color: Theme.palette.baseColor1 + text: qsTr("You can only send direct messages to your Contacts. \n\n +Send a contact request to the person you would like to chat with, you will be\n able to +chat with them once they have accepted your contact request.") + Component.onCompleted: { + if (visible) { + tagSelector.enabled = false; + } + } + } + } +} diff --git a/ui/StatusQ/sandbox/demoapp/StatusAppChatView.qml b/ui/StatusQ/sandbox/demoapp/StatusAppChatView.qml index 19cf4a06c6..a59a2c46d7 100644 --- a/ui/StatusQ/sandbox/demoapp/StatusAppChatView.qml +++ b/ui/StatusQ/sandbox/demoapp/StatusAppChatView.qml @@ -1,4 +1,5 @@ import QtQuick 2.12 +import QtQuick.Layouts 1.12 import StatusQ.Controls 0.1 import StatusQ.Popups 0.1 @@ -11,6 +12,7 @@ import "data" 1.0 StatusAppThreePanelLayout { id: root + property bool createChat: false leftPanel: Item { anchors.fill: parent @@ -23,113 +25,35 @@ StatusAppThreePanelLayout { text: "Chat" } - Item { + RowLayout { id: searchInputWrapper - anchors.top: headline.bottom - anchors.topMargin: 16 width: parent.width height: searchInput.height + anchors.top: headline.bottom + anchors.topMargin: 16 + anchors.right: parent.right + anchors.rightMargin: 8 StatusBaseInput { id: searchInput - - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: actionButton.left - anchors.leftMargin: 16 - anchors.rightMargin: 16 - - height: 36 + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + Layout.leftMargin: 17 + implicitHeight: 36 topPadding: 8 bottomPadding: 0 placeholderText: "Search" icon.name: "search" } - StatusRoundButton { - id: actionButton - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 8 - width: 32 - height: 32 + StatusIconTabButton { + icon.name: "public-chat" + } - type: StatusRoundButton.Type.Secondary - icon.name: "add" - state: "default" - - onClicked: chatContextMenu.popup(actionButton.width-chatContextMenu.width, actionButton.height + 4) - states: [ - State { - name: "default" - PropertyChanges { - target: actionButton - icon.rotation: 0 - highlighted: false - } - }, - State { - name: "pressed" - PropertyChanges { - target: actionButton - icon.rotation: 45 - highlighted: true - } - } - ] - - transitions: [ - Transition { - from: "default" - to: "pressed" - - RotationAnimation { - duration: 150 - direction: RotationAnimation.Clockwise - easing.type: Easing.InCubic - } - }, - Transition { - from: "pressed" - to: "default" - RotationAnimation { - duration: 150 - direction: RotationAnimation.Counterclockwise - easing.type: Easing.OutCubic - } - } - ] - - StatusPopupMenu { - id: chatContextMenu - - onOpened: { - actionButton.state = "pressed" - } - - onClosed: { - actionButton.state = "default" - } - - StatusMenuItem { - text: "Start new chat" - icon.name: "private-chat" - } - - StatusMenuItem { - text: "Start group chat" - icon.name: "group-chat" - } - - StatusMenuItem { - text: "Join public chat" - icon.name: "public-chat" - } - - StatusMenuItem { - text: "Communities" - icon.name: "communities" - } + StatusIconTabButton { + icon.name: "edit" + onClicked: { + root.createChat = !root.createChat; } } } @@ -201,6 +125,25 @@ StatusAppThreePanelLayout { } } + centerPanel: Loader { + anchors.fill: parent + sourceComponent: root.createChat ? createChatView : chatChannelView + } + + Component { + id: createChatView + CreateChatView { + contactsModel: Models.dummyContactsModel + } + } + + Component { + id: chatChannelView + ChatChannelView { + model: Models.chatMessagesModel + } + } + rightPanel: Item { anchors.fill: parent @@ -248,98 +191,4 @@ StatusAppThreePanelLayout { } } } - - centerPanel: ListView { - id: messageList - anchors.fill: parent - anchors.margins: 15 - clip: true - model: Models.chatMessagesModel - delegate: StatusMessage { - id: delegate - width: parent.width - - audioMessageInfoText: "Audio Message" - cancelButtonText: "Cancel" - saveButtonText: "Save" - loadingImageText: "Loading image..." - errorLoadingImageText: "Error loading the image" - resendText: "Resend" - pinnedMsgInfoText: "Pinned by" - - messageDetails: StatusMessageDetails { - contentType: model.contentType - messageContent: model.messageContent - amISender: model.amIsender - displayName: model.userName - secondaryName: model.localName !== "" && model.ensName.startsWith("@") ? model.ensName: "" - chatID: model.chatKey - profileImage: StatusImageSettings { - width: 40 - height: 40 - source: model.profileImage - isIdenticon: model.isIdenticon - } - messageText: model.message - hasMention: model.hasMention - contactType: model.contactType - isPinned: model.isPinned - pinnedBy: model.pinnedBy - hasExpired: model.hasExpired - } - timestamp.text: "10:00 am" - timestamp.tooltip.text: "10:01 am" - // reply related data - isAReply: model.isReply - replyDetails: StatusMessageDetails { - amISender: model.isReply ? model.replyAmISender : "" - displayName: model.isReply ? model.replySenderName: "" - profileImage: StatusImageSettings { - width: 20 - height: 20 - source: model.isReply ? model.replyProfileImage: "" - isIdenticon: model.isReply ? model.replyIsIdenticon: "" - } - messageText: model.isReply ? model.replyMessageText: "" - contentType: model.replyContentType - messageContent: model.replyMessageContent - } - quickActions: [ - StatusFlatRoundButton { - id: emojiBtn - width: 32 - height: 32 - icon.name: "reaction-b" - type: StatusFlatRoundButton.Type.Tertiary - tooltip.text: "Add reaction" - }, - StatusFlatRoundButton { - id: replyBtn - width: 32 - height: 32 - icon.name: "reply" - type: StatusFlatRoundButton.Type.Tertiary - tooltip.text: "Reply" - }, - StatusFlatRoundButton { - width: 32 - height: 32 - icon.name: "tiny/edit" - type: StatusFlatRoundButton.Type.Tertiary - tooltip.text: "Edit" - onClicked: { - delegate.editMode = !delegate.editMode - } - }, - StatusFlatRoundButton { - id: otherBtn - width: 32 - height: 32 - icon.name: "more" - type: StatusFlatRoundButton.Type.Tertiary - tooltip.text: "More" - } - ] - } - } } diff --git a/ui/StatusQ/sandbox/demoapp/data/Models.qml b/ui/StatusQ/sandbox/demoapp/data/Models.qml index 91695fd602..2ee36abae5 100644 --- a/ui/StatusQ/sandbox/demoapp/data/Models.qml +++ b/ui/StatusQ/sandbox/demoapp/data/Models.qml @@ -4,6 +4,58 @@ import StatusQ.Components 0.1 QtObject { + property ListModel dummyContactsModel: ListModel { + ListElement { + publicId: "0x0" + name: "Maria" + icon: "" + isIdenticon: false + onlineStatus: 3 + } + ListElement { + publicId: "0x1" + name: "James" + icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" + isIdenticon: false + onlineStatus: 1 + } + ListElement { + publicId: "0x2" + name: "Paul" + icon: "" + isIdenticon: false + onlineStatus: 2 + } + ListElement { + publicId: "0x3" + name: "Tracy" + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" + isIdenticon: true + onlineStatus: 3 + } + ListElement { + publicId: "0x4" + name: "Nick" + icon: "" + isIdenticon: false + onlineStatus: 3 + } + ListElement { + publicId: "0x5" + name: "Steven" + icon: "" + isIdenticon: false + onlineStatus: 2 + } + ListElement { + publicId: "0x6" + name: "Helen" + icon: "" + isIdenticon: false + onlineStatus: 3 + } + } + property var demoChatListItems: ListModel { id: demoChatListItems ListElement { diff --git a/ui/StatusQ/sandbox/main.qml b/ui/StatusQ/sandbox/main.qml index f9c5ce7b08..15acad15ca 100644 --- a/ui/StatusQ/sandbox/main.qml +++ b/ui/StatusQ/sandbox/main.qml @@ -255,6 +255,11 @@ StatusWindow { selected: viewLoader.source.toString().includes(title) onClicked: mainPageView.page("StatusExpandableSettingsItem"); } + StatusNavigationListItem { + title: "StatusTagSelector" + selected: viewLoader.source.toString().includes(title) + onClicked: mainPageView.page(title); + } StatusListSectionHeadline { text: "StatusQ.Popup" } StatusNavigationListItem { title: "StatusPopupMenu" diff --git a/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml b/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml new file mode 100644 index 0000000000..3de2c69e1d --- /dev/null +++ b/ui/StatusQ/sandbox/pages/StatusTagSelectorPage.qml @@ -0,0 +1,56 @@ +import QtQuick 2.14 + +import StatusQ.Components 0.1 + +Item { + id: root + anchors.fill: parent + + property ListModel asortedContacts: ListModel { + ListElement { + publicId: "0x0" + name: "Maria" + icon: "" + isIdenticon: false + onlineStatus: 3 + } + ListElement { + publicId: "0x1" + name: "James" + icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" + isIdenticon: false + onlineStatus: 1 + } + ListElement { + publicId: "0x2" + name: "Paul" + icon: "" + isIdenticon: false + onlineStatus: 2 + } + ListElement { + publicId: "0x3" + name: "Tracy" + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC" + isIdenticon: true + onlineStatus: 3 + } + ListElement { + publicId: "0x4" + name: "Nick" + icon: "" + isIdenticon: false + onlineStatus: 3 + } + } + + StatusTagSelector { + id: tagSelector + width: 650 + height: 44 + anchors.centerIn: parent + namesModel: root.asortedContacts + toLabelText: qsTr("To: ") + warningText: qsTr("5 USER LIMIT REACHED") + } +} diff --git a/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml b/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml new file mode 100644 index 0000000000..036349554f --- /dev/null +++ b/ui/StatusQ/src/StatusQ/Components/StatusTagSelector.qml @@ -0,0 +1,126 @@ +import QtQuick 2.14 +import QtQuick.Layouts 1.12 +import QtQuick.Controls 2.14 + +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 + +Item { + id: root + + implicitWidth: 448 + implicitHeight: 44 + + property alias textEdit: edit + property alias text: edit.text + property string warningText: "" + property string toLabelText: "" + property int nameCountLimit: 5 + property ListModel namesModel: ListModel { } + + function find(model, criteria) { + for (var i = 0; i < model.count; ++i) if (criteria(model.get(i))) return model.get(i); + return null; + } + + function insertTag(name, id) { + if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) { + namesModel.insert(namesModel.count, {"name": name, "publicId": id}); + edit.clear(); + } + } + + Rectangle { + anchors.fill: parent + radius: 8 + color: Theme.palette.baseColor2 + + RowLayout { + anchors.fill: parent + anchors.leftMargin: 16 + anchors.rightMargin: 16 + spacing: 8 + StatusBaseText { + Layout.preferredWidth: 22 + Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft + color: Theme.palette.baseColor1 + text: root.toLabelText + } + + ListView { + id: namesList + Layout.preferredWidth: (count >= 5) ? (parent.width - warningTextLabel.width - 30) : childrenRect.width + implicitHeight: 30 + visible: (count > 0) + Layout.alignment: Qt.AlignVCenter + model: namesModel + orientation: ListView.Horizontal + spacing: 8 + clip: true + onWidthChanged: { + positionViewAtEnd(); + } + + delegate: Rectangle { + id: nameDelegate + width: (nameText.contentWidth + 34) + height: 30 + color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1 + radius: 8 + StatusBaseText { + id: nameText + 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" + } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + namesModel.remove(index, 1); + } + } + } + } + + TextEdit { + id: edit + Layout.fillWidth: true + Layout.preferredHeight: 44 + verticalAlignment: Text.AlignVCenter + visible: (namesModel.count < 5) + enabled: visible + focus: true + font.pixelSize: 15 + font.family: Theme.palette.baseFont.name + color: Theme.palette.directColor1 + Keys.onPressed: { + if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Escape) + && getText(cursorPosition, (cursorPosition-1)) === "") { + namesModel.remove((namesList.count-1), 1); + } + } + } + + StatusBaseText { + id: warningTextLabel + visible: (namesModel.count === 5) + Layout.preferredWidth: 120 + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + font.pixelSize: 10 + color: Theme.palette.dangerColor1 + text: root.warningText + } + } + } +} diff --git a/ui/StatusQ/src/StatusQ/Components/qmldir b/ui/StatusQ/src/StatusQ/Components/qmldir index 568befdd14..51c84c918e 100644 --- a/ui/StatusQ/src/StatusQ/Components/qmldir +++ b/ui/StatusQ/src/StatusQ/Components/qmldir @@ -26,3 +26,4 @@ StatusExpandableItem 0.1 StatusExpandableItem.qml StatusSmartIdenticon 0.1 StatusSmartIdenticon.qml StatusMessage 0.1 StatusMessage.qml StatusMessageDetails 0.1 StatusMessageDetails.qml +StatusTagSelector 0.1 StatusTagSelector.qml diff --git a/ui/StatusQ/statusq.qrc b/ui/StatusQ/statusq.qrc index 5834670378..3e118610f0 100644 --- a/ui/StatusQ/statusq.qrc +++ b/ui/StatusQ/statusq.qrc @@ -320,5 +320,6 @@ src/StatusQ/Controls/StatusProgressBar.qml src/StatusQ/Controls/StatusPasswordStrengthIndicator.qml src/StatusQ/Components/StatusMemberListItem.qml + src/StatusQ/Components/StatusTagSelector.qml