feat: Add emoji support (#575)

* feat: Add emoji support
1. StatusChatListItem (only updated parts already done by Jo)
2. StatusListItem
3. StatusInput

* feat(StatusColorSelectorGrid): Added new widget for color selection as needed in wallet

* fix(StatusInput): on reset, valid should be set to true else error mode is shown even though the user hasnt entered a value

* fix(StatusLetterIdenticon): Removed the clicked event out from the LetterIdenticon and added it to the StatusBaseInput as other places that use the letterIdenticon dont need the mouse area is not needed
This commit is contained in:
Khushboo-dev-cpp 2022-03-11 20:34:21 +01:00 committed by Michał Cieślak
parent ae3bb01c10
commit 0b4941966e
16 changed files with 239 additions and 10 deletions

View File

@ -67,7 +67,7 @@ GridLayout {
StatusChatListItem {
name: "community-channel-emoji"
type: StatusChatListItem.Type.CommunityChat
emoji: "😁"
icon.emoji: "😁"
}
StatusChatListItem {
@ -338,6 +338,15 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
}
}
StatusListItem {
title: "List Item with Emoji"
subTitle: "Emoji"
icon.emoji: "😁"
icon.color: "yellow"
icon.letterSize: 14
icon.isLetterIdenticon: true
}
StatusDescriptionListItem {
title: "Title"
subTitle: "Subtitle"

View File

@ -293,6 +293,11 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusColorSelectorGrid"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
}
}
}

View File

@ -0,0 +1,36 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
width: 800
height: 100
Row {
id: selectedColor
anchors.top: parent.top
anchors.left: colorSelectionGrid.left
spacing: 10
StatusBaseText {
text: "SelectedColor is"
}
Rectangle {
width: 100
height: 20
radius: width/2
color: colorSelectionGrid.selectedColor
}
}
StatusColorSelectorGrid {
id: colorSelectionGrid
anchors.top: selectedColor.bottom
anchors.topMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
titleText: "COLOR"
selectedColorIndex: 2
}
}

View File

@ -130,4 +130,27 @@ Column {
input.minimumHeight: 80
input.maximumHeight: 200
}
StatusInput {
label: "Input with emoji icon"
input.placeholderText: "Enter Name"
input.icon.emoji: "😁"
input.icon.color: "blue"
input.isIconSelectable: true
onIconClicked: {
// launch emoji popup
}
}
StatusInput {
label: "Input with selectable icon which is not an emoji"
input.placeholderText: "Enter Name"
input.icon.emoji: ""
input.icon.name: "filled-account"
input.icon.color: "blue"
input.isIconSelectable: true
onIconClicked: {
// launch emoji popup
}
}
}

View File

@ -97,7 +97,7 @@ Column {
chatId: model.itemId
categoryId: model.parentItemId? model.parentItemId : ""
name: model.name
emoji: model.emoji
icon.emoji: model.emoji
type: !!model.type ? model.type : StatusChatListItem.Type.CommunityChat
muted: model.muted
hasUnreadMessages: model.hasUnreadMessages

View File

@ -16,7 +16,6 @@ Rectangle {
property string chatId: ""
property string categoryId: ""
property string name: ""
property string emoji: ""
property alias badge: statusBadge
property bool hasUnreadMessages: false
property int notificationsCount: 0
@ -30,6 +29,7 @@ Rectangle {
height: 24
color: Theme.palette.miscColor5
letterSize: emoji ? 14 : 15
emoji: ""
}
property int type: StatusChatListItem.Type.PublicChat
property bool highlighted: false
@ -86,7 +86,6 @@ Rectangle {
image: statusChatListItem.image
icon: statusChatListItem.icon
name: statusChatListItem.name
emoji: statusChatListItem.emoji
}
StatusIcon {

View File

@ -21,7 +21,10 @@ Rectangle {
id: identiconText
text: {
if (emoji) {
return Emoji.parse(emoji)
if(Utils.isHtml(emoji))
return emoji
else
return Emoji.parse(emoji)
}
return (((statusLetterIdenticon.name.charAt(0) === "#")
|| (statusLetterIdenticon.name.charAt(0) === "@") ?
@ -31,6 +34,9 @@ Rectangle {
font.weight: Font.Bold
font.pixelSize: statusLetterIdenticon.letterSize
color: Qt.rgba(255, 255, 255, 0.7)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.alignWhenCentered: false
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}

View File

@ -8,7 +8,6 @@ Loader {
property string name: ""
property int charCount: 1
property string emoji: ""
property int dZ: 100
// Badge color properties must be set if badgeItem.visible = true
@ -85,7 +84,7 @@ Loader {
height: statusSmartIdenticon.icon.height
color: statusSmartIdenticon.icon.color
name: statusSmartIdenticon.name
emoji: statusSmartIdenticon.emoji
emoji: statusSmartIdenticon.icon.emoji
letterSize: statusSmartIdenticon.icon.letterSize
charCount: statusSmartIdenticon.charCount
}

View File

@ -2,6 +2,7 @@ import QtQuick 2.14
import QtQuick.Controls 2.14 as QC
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
@ -49,16 +50,26 @@ Item {
property bool dirty: false
property bool pending: false
property bool leftIcon: true
property bool isIconSelectable: false
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
name: ""
color: Theme.palette.baseColor1
emoji: ""
letterSize: 14
background: StatusIconBackgroundSettings {
width: 30
height: 30
color: Theme.palette.indirectColor1
}
}
property Item component
signal iconClicked()
onClearableChanged: {
if (clearable && !component) {
clearButtonLoader.active = true
@ -109,6 +120,29 @@ Item {
edit.forceActiveFocus()
}
StatusSmartIdenticon {
id: emoji
anchors.left: parent.left
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
icon.width: !statusBaseInput.icon.emoji ? 20 : 30
icon.height: !statusBaseInput.icon.emoji ? 20 : 30
icon.background: statusBaseInput.icon.background
icon.color: statusBaseInput.icon.color
icon.letterSize: statusBaseInput.icon.letterSize
icon.emoji: statusBaseInput.icon.emoji
icon.name: !statusBaseInput.icon.emoji ? statusBaseInput.icon.name : ""
visible: (!!statusBaseInput.icon.emoji || !!statusBaseInput.icon.name) && statusBaseInput.isIconSelectable
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
enabled: emoji.visible
onClicked: statusBaseInput.iconClicked()
}
}
StatusIcon {
id: statusIcon
anchors.topMargin: 10
@ -121,7 +155,7 @@ Item {
width: statusBaseInput.icon.width
height: statusBaseInput.icon.height
color: statusBaseInput.icon.color
visible: !!statusBaseInput.icon.name
visible: !!statusBaseInput.icon.name && !statusBaseInput.isIconSelectable
}
Flickable {
@ -129,7 +163,7 @@ Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: (statusIcon.visible && statusBaseInput.leftIcon) ?
statusIcon.right : parent.left
statusIcon.right : emoji.visible ? emoji.right: parent.left
anchors.right: {
if (!!statusBaseInput.component) {
return statusBaseInputComponentSlot.left

View File

@ -0,0 +1,32 @@
import QtQuick 2.13
import QtQuick.Controls 2.14
import StatusQ.Core.Theme 0.1
RadioButton {
id: control
property string radioButtonColor: ""
property string selectionColor: StatusColors.colors['white']
implicitWidth: 48
implicitHeight: 48
indicator: Rectangle {
implicitWidth: 48
implicitHeight: 48
radius: width/2
color: radioButtonColor
Rectangle {
width: 20
height: 20
radius: width/2
color: selectionColor
border.color: StatusColors.colors['grey3']
visible: control.checked
anchors.centerIn: parent
}
}
}

View File

@ -0,0 +1,56 @@
import QtQuick 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import "./"
Column {
id: root
property alias titleText: title.text
property alias title: title
property int selectedColorIndex: 0
property string selectedColor: ""
property var model: [StatusColors.colors['black'],
StatusColors.colors['grey'],
StatusColors.colors['blue2'],
StatusColors.colors['purple'],
StatusColors.colors['cyan'],
StatusColors.colors['violet'],
StatusColors.colors['red2'],
StatusColors.colors['yellow'],
StatusColors.colors['green2'],
StatusColors.colors['moss'],
StatusColors.colors['brown'],
StatusColors.colors['brown2']]
spacing: 16
StatusBaseText {
id: title
verticalAlignment: Text.AlignVCenter
font.pixelSize: 13
color: Theme.palette.baseColor1
}
Grid {
columns: 6
rowSpacing: 16
columnSpacing: 32
Repeater {
model: root.model
delegate: StatusColorRadioButton {
checked: index === selectedColorIndex
radioButtonColor: root.model[index] || "transparent"
onCheckedChanged: {
if(checked) {
selectedColorIndex = index
selectedColor = root.model[index]
}
}
}
}
}
}

View File

@ -40,6 +40,8 @@ Item {
property var pendingValidators: []
signal iconClicked()
enum ValidationMode {
OnlyWhenDirty, // validates input only after it has become dirty
Always // validates input even before it has become dirty
@ -49,7 +51,7 @@ Item {
property var asyncErrors: ({})
function reset() {
statusBaseInput.valid = false
statusBaseInput.valid = true
statusBaseInput.pristine = true
statusBaseInput.text = ""
root.errorMessage = ""
@ -189,6 +191,7 @@ Item {
onTextChanged: root.validate()
Keys.forwardTo: [root]
onIconClicked: root.iconClicked()
}
StatusBaseText {

View File

@ -33,3 +33,4 @@ StatusSwitchTabBar 0.1 StatusSwitchTabBar.qml
StatusSelectableText 0.1 StatusSelectableText.qml
StatusWalletColorButton 0.1 StatusWalletColorButton.qml
StatusWalletColorSelect 0.1 StatusWalletColorSelect.qml
StatusColorSelectorGrid 0.1 StatusColorSelectorGrid.qml

View File

@ -13,5 +13,6 @@ QtObject {
property int rotation
property bool isLetterIdenticon
property int letterSize
property string emoji
property StatusIconBackgroundSettings background: StatusIconBackgroundSettings {}
}

View File

@ -4,6 +4,7 @@ import QtQuick 2.13
//import shared.status 1.0
import "../../../assets/twemoji/twemoji.js" as Twemoji
import "./emojiList.js" as EmojiJSON
QtObject {
readonly property var size: {
@ -94,4 +95,24 @@ QtObject {
}
return undefined
}
function getRandomEmoji() {
var randomEmoji = EmojiJSON.emoji_json[Math.floor(Math.random() * EmojiJSON.emoji_json.length)]
const extenstionIndex = randomEmoji.unicode.lastIndexOf('.');
let iconCodePoint = randomEmoji.unicode
if (extenstionIndex > -1) {
iconCodePoint = iconCodePoint.substring(0, extenstionIndex)
}
// Split the unicode to get all the parts and then encode them from hex to utf8
const splitCodePoint = iconCodePoint.split('-')
let codePointParts = []
splitCodePoint.forEach(function (codePoint) {
codePointParts.push(`0x${codePoint}`)
})
const encodedIcon = String.fromCodePoint(...codePointParts);
return Emoji.parse(encodedIcon) + ' '
}
}

View File

@ -70,6 +70,10 @@ QtObject {
}
return strNumber.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1')
}
function isHtml(text) {
return (/<\/?[a-z][\s\S]*>/i.test(text))
}
}