From e1c9570e89609c7c1fe042352215a5ae005cb2a6 Mon Sep 17 00:00:00 2001 From: Pascal Precht Date: Tue, 25 May 2021 12:47:23 +0200 Subject: [PATCH] feat(Components): introduce StatusChatListItem This introduces the brand new `StatusChatListItem` which can be used to render channels, one-to-one chats and community channels in Status applications. The component can be used as follows: ```qml import Status.Components 0.1 StatusChatListItem { name: "channel-name" // name of channel or user type: StatusChatListItem.Type.PublicChat // GroupChat | CommunityChat | OneToOneChat image.source: "profile/image/source" // uses letter identicon instead of not supplied hasUnreadMessages: true // default `false` badge.value: 1 // default `0` muted: true // `default `false` selected: true // default `false` onUnmute: ... // signal when unmute icon is clicked } ``` Closes #65 --- ui/StatusQ/sandbox/ListItems.qml | 59 +++++ .../StatusQ/Components/StatusChatListItem.qml | 202 ++++++++++++++++++ ui/StatusQ/src/StatusQ/Components/qmldir | 1 + .../StatusQ/Core/Theme/StatusDarkTheme.qml | 7 + .../StatusQ/Core/Theme/StatusLightTheme.qml | 7 + .../src/StatusQ/Core/Theme/ThemePalette.qml | 7 + .../src/assets/img/icons/channel-white.svg | 3 + .../src/assets/img/icons/group-white.svg | 7 + .../src/assets/img/icons/muted-white.svg | 5 + ui/StatusQ/src/assets/img/icons/muted.svg | 4 + .../assets/img/icons/public-chat-white.svg | 4 + .../src/assets/img/icons/public-chat.svg | 5 +- 12 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml create mode 100644 ui/StatusQ/src/assets/img/icons/channel-white.svg create mode 100644 ui/StatusQ/src/assets/img/icons/group-white.svg create mode 100644 ui/StatusQ/src/assets/img/icons/muted-white.svg create mode 100644 ui/StatusQ/src/assets/img/icons/muted.svg create mode 100644 ui/StatusQ/src/assets/img/icons/public-chat-white.svg diff --git a/ui/StatusQ/sandbox/ListItems.qml b/ui/StatusQ/sandbox/ListItems.qml index be94da0848..071dfb903f 100644 --- a/ui/StatusQ/sandbox/ListItems.qml +++ b/ui/StatusQ/sandbox/ListItems.qml @@ -10,6 +10,65 @@ GridLayout { columnSpacing: 5 rowSpacing: 5 + StatusChatListItem { + id: test + name: "public-channel" + type: StatusChatListItem.Type.PublicChat + } + + StatusChatListItem { + name: "group-chat" + type: StatusChatListItem.Type.GroupChat + } + + StatusChatListItem { + name: "community-channel" + type: StatusChatListItem.Type.CommunityChat + } + + StatusChatListItem { + name: "community-channel-with-image" + image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" + type: StatusChatListItem.Type.CommunityChat + } + + StatusChatListItem { + name: "Weird Crazy Otter" + image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg" + type: StatusChatListItem.Type.OneToOneChat + } + + StatusChatListItem { + name: "has-unread-messages" + type: StatusChatListItem.Type.PublicChat + hasUnreadMessages: true + } + + StatusChatListItem { + name: "has-mentions" + type: StatusChatListItem.Type.PublicChat + badge.value: 1 + } + + StatusChatListItem { + name: "is-muted" + type: StatusChatListItem.Type.PublicChat + muted: true + onUnmute: muted = false + } + + StatusChatListItem { + name: "selected-channel" + type: StatusChatListItem.Type.PublicChat + selected: true + } + StatusChatListItem { + name: "selected-muted-channel" + type: StatusChatListItem.Type.PublicChat + selected: true + muted: true + } + StatusListItem { title: "Title" } diff --git a/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml new file mode 100644 index 0000000000..6122b24649 --- /dev/null +++ b/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml @@ -0,0 +1,202 @@ +import QtQuick 2.13 +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Components 0.1 +import StatusQ.Controls 0.1 + +Rectangle { + id: statusChatListItem + + property string name: "" + property alias badge: statusBadge + property bool hasUnreadMessages: false + property bool hasMention: false + property bool muted: false + property StatusImageSettings image: StatusImageSettings {} + property StatusIconSettings icon: StatusIconSettings { + color: Theme.palette.miscColor5 + } + property int type: StatusChatListItem.Type.PublicChat + property bool selected: false + + signal clicked(var mouse) + signal unmute() + + enum Type { + PublicChat, + GroupChat, + CommunityChat, + OneToOneChat + } + + implicitWidth: 287 + implicitHeight: 40 + + radius: 8 + + color: { + if (selected) { + return Theme.palette.statusChatListItem.selectedBackgroundColor + } + return sensor.containsMouse ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4 + } + + MouseArea { + id: sensor + + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + hoverEnabled: true + + onClicked: statusChatListItem.clicked(mouse) + + Loader { + id: identicon + anchors.left: parent.left + anchors.leftMargin: 8 + anchors.verticalCenter: parent.verticalCenter + + sourceComponent: !!statusChatListItem.image.source.toString() ? + statusRoundedImageCmp : statusLetterIdenticonCmp + } + + Component { + id: statusLetterIdenticonCmp + StatusLetterIdenticon { + height: 24 + width: 24 + name: statusChatListItem.name + letterSize: 15 + color: statusChatListItem.icon.color + } + } + + Component { + id: statusRoundedImageCmp + Item { + height: 24 + width: 24 + StatusRoundedImage { + id: statusRoundedImage + width: parent.width + height: parent.height + image.source: statusChatListItem.image.source + } + + Loader { + sourceComponent: { + switch (statusRoundedImage.image.status) { + case Image.Loading: + return statusLoadingIndicator + break; + case Image.Error: + return statusLetterIdenticonCmp + break; + } + } + } + + Component { + id: statusLoadingIndicator + StatusLoadingIndicator { + color: Theme.palette.directColor6 + } + } + } + } + + StatusIcon { + id: statusIcon + anchors.left: identicon.right + anchors.leftMargin: 8 + anchors.verticalCenter: parent.verticalCenter + + width: 14 + visible: statusChatListItem.type !== StatusChatListItem.Type.OneToOneChat + opacity: { + if (statusChatListItem.muted && !sensor.containsMouse) { + return 0.4 + } + return statusChatListItem.hasMention || + statusChatListItem.hasUnreadMessages || + statusChatListItem.selected || + statusBadge.visible || + sensor.containsMouse ? 1.0 : 0.7 + } + + icon: { + switch (statusChatListItem.type) { + case StatusChatListItem.Type.PublicCat: + return Theme.palette.name == "light" ? "public-chat" : "public-chat-white" + break; + case StatusChatListItem.Type.GroupChat: + return Theme.palette.name == "light" ? "group" : "group-white" + break; + case StatusChatListItem.Type.CommunityChat: + return Theme.palette.name == "light" ? "channel" : "channel-white" + break; + default: + return Theme.palette.name == "light" ? "public-chat" : "public-chat-white" + } + } + } + + StatusBaseText { + id: chatName + anchors.left: statusIcon.visible ? statusIcon.right : identicon.right + anchors.leftMargin: statusIcon.visible ? 1 : 8 + anchors.verticalCenter: parent.verticalCenter + + text: statusChatListItem.name + color: { + if (statusChatListItem.muted && !sensor.containsMouse) { + return Theme.palette.directColor5 + } + return statusChatListItem.hasMention || + statusChatListItem.hasUnreadMessages || + statusChatListItem.selected || + sensor.containsMouse || + statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4 + } + font.weight: statusChatListItem.hasMention || + statusChatListItem.hasUnreadMessages || + statusBadge.visible ? Font.Bold : Font.Medium + } + + StatusBadge { + id: statusBadge + + anchors.right: mutedIcon.visible ? mutedIcon.left : parent.right + anchors.rightMargin: 8 + anchors.verticalCenter: parent.verticalCenter + + border.width: 4 + border.color: color + visible: statusBadge.value > 0 + } + + StatusIcon { + id: mutedIcon + anchors.right: parent.right + anchors.rightMargin: 8 + anchors.verticalCenter: parent.verticalCenter + width: 14 + opacity: mutedIconSensor.containsMouse ? 1.0 : 0.2 + icon: Theme.palette.name === "light" ? "muted" : "muted-white" + visible: statusChatListItem.muted + + MouseArea { + id: mutedIconSensor + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + onClicked: statusChatListItem.unmute() + } + + StatusToolTip { + text: "Unmute" + visible: mutedIconSensor.containsMouse + } + } + } +} diff --git a/ui/StatusQ/src/StatusQ/Components/qmldir b/ui/StatusQ/src/StatusQ/Components/qmldir index 60654f5421..c4cdd01e9a 100644 --- a/ui/StatusQ/src/StatusQ/Components/qmldir +++ b/ui/StatusQ/src/StatusQ/Components/qmldir @@ -1,6 +1,7 @@ module StatusQ.Components StatusBadge 0.1 StatusBadge.qml +StatusChatListItem 0.1 StatusChatListItem.qml StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml StatusListItem 0.1 StatusListItem.qml StatusLoadingIndicator 0.1 StatusLoadingIndicator.qml diff --git a/ui/StatusQ/src/StatusQ/Core/Theme/StatusDarkTheme.qml b/ui/StatusQ/src/StatusQ/Core/Theme/StatusDarkTheme.qml index 083cc4ab40..a4408ab75c 100644 --- a/ui/StatusQ/src/StatusQ/Core/Theme/StatusDarkTheme.qml +++ b/ui/StatusQ/src/StatusQ/Core/Theme/StatusDarkTheme.qml @@ -2,6 +2,8 @@ import QtQuick 2.13 ThemePalette { + name: "dark" + property QtObject baseFont: FontLoader { source: "../../../assets/fonts/Inter/Inter-Regular.otf" } @@ -125,6 +127,11 @@ ThemePalette { property color backgroundColor: baseColor3 } + property QtObject statusChatListItem: QtObject { + property color hoverBackgroundColor: directColor8 + property color selectedBackgroundColor: directColor7 + } + property QtObject statusBadge: QtObject { property color foregroundColor: baseColor3 } diff --git a/ui/StatusQ/src/StatusQ/Core/Theme/StatusLightTheme.qml b/ui/StatusQ/src/StatusQ/Core/Theme/StatusLightTheme.qml index e994c7189f..81fdc7e8ee 100644 --- a/ui/StatusQ/src/StatusQ/Core/Theme/StatusLightTheme.qml +++ b/ui/StatusQ/src/StatusQ/Core/Theme/StatusLightTheme.qml @@ -2,6 +2,8 @@ import QtQuick 2.13 ThemePalette { + name: "light" + property QtObject baseFont: FontLoader { source: "../../../assets/fonts/Inter/Inter-Regular.otf" } @@ -125,6 +127,11 @@ ThemePalette { property color backgroundColor: white } + property QtObject statusChatListItem: QtObject { + property color hoverBackgroundColor: baseColor2 + property color selectedBackgroundColor: baseColor3 + } + property QtObject statusBadge: QtObject { property color foregroundColor: white } diff --git a/ui/StatusQ/src/StatusQ/Core/Theme/ThemePalette.qml b/ui/StatusQ/src/StatusQ/Core/Theme/ThemePalette.qml index 3f220a0232..7d56f0ac8e 100644 --- a/ui/StatusQ/src/StatusQ/Core/Theme/ThemePalette.qml +++ b/ui/StatusQ/src/StatusQ/Core/Theme/ThemePalette.qml @@ -4,6 +4,8 @@ QtObject { id: theme + property string name + property FontLoader baseFont property FontLoader baseFontThin property FontLoader baseFontExtraLight @@ -86,6 +88,11 @@ QtObject { property color backgroundColor } + property QtObject statusChatListItem: QtObject { + property color hoverBackgroundColor + property color selectedBackgroundColor + } + property QtObject statusBadge: QtObject { property color foregroundColor } diff --git a/ui/StatusQ/src/assets/img/icons/channel-white.svg b/ui/StatusQ/src/assets/img/icons/channel-white.svg new file mode 100644 index 0000000000..6bed0a4132 --- /dev/null +++ b/ui/StatusQ/src/assets/img/icons/channel-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/ui/StatusQ/src/assets/img/icons/group-white.svg b/ui/StatusQ/src/assets/img/icons/group-white.svg new file mode 100644 index 0000000000..64303730cc --- /dev/null +++ b/ui/StatusQ/src/assets/img/icons/group-white.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/ui/StatusQ/src/assets/img/icons/muted-white.svg b/ui/StatusQ/src/assets/img/icons/muted-white.svg new file mode 100644 index 0000000000..9f559a16f3 --- /dev/null +++ b/ui/StatusQ/src/assets/img/icons/muted-white.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ui/StatusQ/src/assets/img/icons/muted.svg b/ui/StatusQ/src/assets/img/icons/muted.svg new file mode 100644 index 0000000000..2564a9ea05 --- /dev/null +++ b/ui/StatusQ/src/assets/img/icons/muted.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ui/StatusQ/src/assets/img/icons/public-chat-white.svg b/ui/StatusQ/src/assets/img/icons/public-chat-white.svg new file mode 100644 index 0000000000..72cf0af2af --- /dev/null +++ b/ui/StatusQ/src/assets/img/icons/public-chat-white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/ui/StatusQ/src/assets/img/icons/public-chat.svg b/ui/StatusQ/src/assets/img/icons/public-chat.svg index d1305748e9..92e866f248 100644 --- a/ui/StatusQ/src/assets/img/icons/public-chat.svg +++ b/ui/StatusQ/src/assets/img/icons/public-chat.svg @@ -1,3 +1,4 @@ - - + + +