Implement sending stickers

MSC2545 image packs are used as source.
This commit is contained in:
Tobias Fella
2023-05-05 14:29:18 +00:00
parent 443d709eb8
commit 96c1b98d02
15 changed files with 622 additions and 24 deletions

View File

@@ -54,7 +54,7 @@ QQC2.Control {
property bool isBusy: false
icon.name: "smiley"
text: i18n("Add an Emoji")
text: i18n("Emojis & Stickers")
displayHint: Kirigami.DisplayHint.IconOnly
checkable: true
@@ -367,7 +367,7 @@ QQC2.Control {
EmojiDialog {
id: emojiDialog
x: parent.width - implicitWidth
x: parent.width - width
y: -implicitHeight // - Kirigami.Units.smallSpacing
modal: false

View File

@@ -11,6 +11,7 @@ QQC2.ItemDelegate {
property string name
property string emoji
property bool showTones: false
property bool isImage: false
QQC2.ToolTip.text: emojiDelegate.name
QQC2.ToolTip.visible: hovered && emojiDelegate.name !== ""
@@ -23,7 +24,7 @@ QQC2.ItemDelegate {
contentItem: Item {
Kirigami.Heading {
anchors.fill: parent
visible: !emojiDelegate.emoji.startsWith("image")
visible: !emojiDelegate.emoji.startsWith("image") && !emojiDelegate.isImage
text: emojiDelegate.emoji
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@@ -40,7 +41,7 @@ QQC2.ItemDelegate {
}
Image {
anchors.fill: parent
visible: emojiDelegate.emoji.startsWith("image")
visible: emojiDelegate.emoji.startsWith("image") || emojiDelegate.isImage
source: visible ? emojiDelegate.emoji : ""
}
}

View File

@@ -16,8 +16,10 @@ QQC2.ScrollView {
required property bool withCustom
readonly property var searchCategory: withCustom ? EmojiModel.Search : EmojiModel.SearchNoCustom
required property QtObject header
property bool stickers: false
signal chosen(string unicode)
signal stickerChosen(int index)
onActiveFocusChanged: if (activeFocus) {
emojis.forceActiveFocus()
@@ -48,15 +50,19 @@ QQC2.ScrollView {
delegate: EmojiDelegate {
id: emojiDelegate
checked: emojis.currentIndex === model.index
emoji: modelData.unicode
name: modelData.shortName
emoji: !!modelData ? modelData.unicode : model.url
name: !!modelData ? modelData.shortName : model.body
width: emojis.cellWidth
height: emojis.cellHeight
isImage: emojiGrid.stickers
Keys.onEnterPressed: clicked()
Keys.onReturnPressed: clicked()
onClicked: {
if (emojiGrid.stickers) {
emojiGrid.stickerChosen(model.index)
}
emojiGrid.chosen(modelData.isCustom ? modelData.shortName : modelData.unicode)
EmojiModel.emojiUsed(modelData)
}
@@ -69,7 +75,7 @@ QQC2.ScrollView {
tones.open()
tones.forceActiveFocus()
}
showTones: EmojiModel.tones(modelData.shortName).length > 0
showTones: !!modelData && EmojiModel.tones(modelData.shortName).length > 0
}
Kirigami.PlaceholderMessage {

View File

@@ -24,15 +24,45 @@ ColumnLayout {
readonly property int categoryIconSize: Math.round(Kirigami.Units.gridUnit * 2.5)
readonly property var currentCategory: currentEmojiModel[categories.currentIndex].category
readonly property alias categoryCount: categories.count
property int selectedType: 0
signal chosen(string emoji)
onActiveFocusChanged: if (activeFocus) {
searchField.forceActiveFocus()
searchField.forceActiveFocus();
}
spacing: 0
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: root.categoryIconSize
Item {
Layout.preferredHeight: 1
Layout.fillWidth: true
}
CategoryIcon {
id: emojis
source: "smiley"
text: i18n("Emojis")
t: 0
}
CategoryIcon {
id: stickers
source: "stickers"
text: i18n("Stickers")
t: 1
}
Item {
Layout.preferredHeight: 1
Layout.fillWidth: true
}
}
QQC2.ScrollView {
Layout.fillWidth: true
Layout.preferredHeight: root.categoryIconSize + QQC2.ScrollBar.horizontal.height
@@ -46,6 +76,7 @@ ColumnLayout {
Keys.onReturnPressed: if (emojiGrid.count > 0) emojiGrid.focus = true
Keys.onEnterPressed: if (emojiGrid.count > 0) emojiGrid.focus = true
KeyNavigation.down: emojiGrid.count > 0 ? emojiGrid : categories
KeyNavigation.tab: emojiGrid.count > 0 ? emojiGrid : categories
@@ -54,22 +85,10 @@ ColumnLayout {
Keys.forwardTo: searchField
interactive: width !== contentWidth
model: root.currentEmojiModel
model: root.selectedType === 0 ? root.currentEmojiModel : stickerPackModel
Component.onCompleted: categories.forceActiveFocus()
delegate: EmojiDelegate {
width: root.categoryIconSize
height: width
checked: categories.currentIndex === model.index
emoji: modelData.emoji
name: modelData.name
onClicked: {
categories.currentIndex = index
categories.focus = true
}
}
delegate: root.selectedType === 0 ? emojiDelegate : stickerDelegate
}
}
@@ -82,6 +101,7 @@ ColumnLayout {
id: searchField
Layout.margins: Kirigami.Units.smallSpacing
Layout.fillWidth: true
visible: selectedType === 0
/**
* The focus is manged by the parent and we don't want to use the standard
@@ -93,13 +113,15 @@ ColumnLayout {
EmojiGrid {
id: emojiGrid
targetIconSize: root.currentCategory === EmojiModel.Custom ? Kirigami.Units.gridUnit * 3 : root.categoryIconSize // Custom emojis are bigger
model: searchField.text.length === 0 ? EmojiModel.emojis(root.currentCategory) : (root.includeCustom ? EmojiModel.filterModel(searchField.text, false) : EmojiModel.filterModelNoCustom(searchField.text, false))
model: root.selectedType === 1 ? stickerModel : searchField.text.length === 0 ? EmojiModel.emojis(root.currentCategory) : (root.includeCustom ? EmojiModel.filterModel(searchField.text, false) : EmojiModel.filterModelNoCustom(searchField.text, false))
Layout.fillWidth: true
Layout.fillHeight: true
withCustom: root.includeCustom
onChosen: root.chosen(unicode)
header: categories
Keys.forwardTo: searchField
stickers: root.selectedType === 1
onStickerChosen: stickerModel.postSticker(index)
}
Kirigami.Separator {
@@ -132,4 +154,86 @@ ColumnLayout {
orientation: Qt.Horizontal
}
}
ImagePacksModel {
id: stickerPackModel
room: currentRoom
showStickers: true
showEmoticons: false
}
StickerModel {
id: stickerModel
model: stickerPackModel
packIndex: 0
room: currentRoom
}
Component {
id: emojiDelegate
EmojiDelegate {
width: root.categoryIconSize
height: width
checked: categories.currentIndex === model.index
emoji: modelData ? modelData.emoji : ""
name: modelData ? modelData.name : ""
onClicked: {
categories.currentIndex = index;
categories.focus = true;
}
}
}
Component {
id: stickerDelegate
EmojiDelegate {
width: root.categoryIconSize
height: width
emoji: model.avatarUrl ?? ""
isImage: true
name: model.displayName ?? ""
onClicked: stickerModel.packIndex = model.index
checked: stickerModel.packIndex === model.index
}
}
component CategoryIcon : Kirigami.Icon {
id: categoryIcons
readonly property bool checked: root.selectedType === t
required property int t
required property string text
Layout.preferredWidth: root.categoryIconSize
Layout.preferredHeight: root.categoryIconSize
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: categoryIconsMouseArea.containsMouse
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
MouseArea {
id: categoryIconsMouseArea
hoverEnabled: true
anchors.fill: parent
onClicked: root.selectedType = t
}
Rectangle {
color: categoryIcons.checked ? Kirigami.Theme.highlightColor : "transparent"
radius: Kirigami.Units.smallSpacing
z: -1
anchors {
fill: parent
margins: Kirigami.Units.smallSpacing
}
Rectangle {
radius: Kirigami.Units.smallSpacing
anchors.fill: parent
color: Kirigami.Theme.highlightColor
opacity: categoryIconsMouseArea.containsMouse && !categoryIconsMouseArea.pressed ? 0.2 : 0
}
}
}
}

View File

@@ -48,7 +48,7 @@ QQC2.Popup {
padding: 2
implicitHeight: Kirigami.Units.gridUnit * 20 + 2 * padding
width: Math.min(contentItem.categoryIconSize * contentItem.categoryCount + 2 * padding, QQC2.Overlay.overlay.width)
width: Math.min(contentItem.categoryIconSize * 11 + 2 * padding, QQC2.Overlay.overlay.width)
contentItem: EmojiPicker {
id: emojiPicker
height: 400

View File

@@ -49,6 +49,11 @@ Kirigami.CategorizedSettings {
text: i18n("Notifications")
icon.name: "notifications"
page: Qt.resolvedUrl("PushNotification.qml")
},
Kirigami.SettingAction {
text: i18n("Stickers")
icon.name: "stickers"
page: Qt.resolvedUrl("RoomStickers.qml")
initialProperties: {
return {
room: root.room

View File

@@ -38,6 +38,12 @@ Kirigami.CategorizedSettings {
icon.name: "preferences-desktop-emoticons"
page: Qt.resolvedUrl("Emoticons.qml")
},
Kirigami.SettingAction {
actionName: "stickers"
text: i18n("Stickers")
icon.name: "stickers"
page: Qt.resolvedUrl("Emoticons.qml")
},
Kirigami.SettingAction {
actionName: "spellChecking"
text: i18n("Spell Checking")