Implement sending stickers
MSC2545 image packs are used as source.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 : ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user