Warning, /network/neochat/src/qml/EmojiPicker.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2022 Tobias Fella <tobias.fella@kde.org> 0002 // SPDX-License-Identifier: GPL-2.0-or-later 0003 0004 import QtQuick 0005 import QtQuick.Controls as QQC2 0006 import QtQuick.Layouts 0007 import org.kde.kirigami as Kirigami 0008 import org.kde.neochat 0009 0010 ColumnLayout { 0011 id: root 0012 0013 /** 0014 * @brief The current room that user is viewing. 0015 */ 0016 property NeoChatRoom currentRoom 0017 0018 property bool includeCustom: false 0019 property bool showQuickReaction: false 0020 0021 readonly property var currentEmojiModel: { 0022 if (includeCustom) { 0023 EmojiModel.categoriesWithCustom; 0024 } else { 0025 EmojiModel.categories; 0026 } 0027 } 0028 0029 readonly property int categoryIconSize: Math.round(Kirigami.Units.gridUnit * 2.5) 0030 readonly property var currentCategory: currentEmojiModel[categories.currentIndex].category 0031 readonly property alias categoryCount: categories.count 0032 property int selectedType: 0 0033 0034 signal chosen(string emoji) 0035 0036 onActiveFocusChanged: if (activeFocus) { 0037 searchField.forceActiveFocus(); 0038 } 0039 0040 spacing: 0 0041 0042 Kirigami.NavigationTabBar { 0043 id: types 0044 Layout.fillWidth: true 0045 Kirigami.Theme.colorSet: Kirigami.Theme.View 0046 0047 background: null 0048 actions: [ 0049 Kirigami.Action { 0050 id: emojis 0051 icon.name: "smiley" 0052 text: i18n("Emojis") 0053 checked: true 0054 onTriggered: root.selectedType = 0 0055 }, 0056 Kirigami.Action { 0057 id: stickers 0058 icon.name: "stickers" 0059 text: i18n("Stickers") 0060 onTriggered: root.selectedType = 1 0061 } 0062 ] 0063 } 0064 0065 QQC2.ScrollView { 0066 Layout.fillWidth: true 0067 Layout.preferredHeight: root.categoryIconSize + QQC2.ScrollBar.horizontal.height 0068 QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0 0069 0070 ListView { 0071 id: categories 0072 clip: true 0073 focus: true 0074 orientation: ListView.Horizontal 0075 0076 Keys.onReturnPressed: if (emojiGrid.count > 0) { 0077 emojiGrid.focus = true; 0078 } 0079 Keys.onEnterPressed: if (emojiGrid.count > 0) { 0080 emojiGrid.focus = true; 0081 } 0082 0083 KeyNavigation.down: emojiGrid.count > 0 ? emojiGrid : categories 0084 KeyNavigation.tab: emojiGrid.count > 0 ? emojiGrid : categories 0085 0086 keyNavigationEnabled: true 0087 keyNavigationWraps: true 0088 Keys.forwardTo: searchField 0089 interactive: width !== contentWidth 0090 0091 model: root.selectedType === 0 ? root.currentEmojiModel : stickerPackModel 0092 Component.onCompleted: categories.forceActiveFocus() 0093 0094 delegate: root.selectedType === 0 ? emojiDelegate : stickerDelegate 0095 } 0096 } 0097 0098 Kirigami.Separator { 0099 Layout.fillWidth: true 0100 Layout.preferredHeight: 1 0101 } 0102 0103 Kirigami.SearchField { 0104 id: searchField 0105 Layout.margins: Kirigami.Units.smallSpacing 0106 Layout.fillWidth: true 0107 visible: selectedType === 0 0108 0109 /** 0110 * The focus is manged by the parent and we don't want to use the standard 0111 * shortcut as it could block other SearchFields from using it. 0112 */ 0113 focusSequence: "" 0114 } 0115 0116 EmojiGrid { 0117 id: emojiGrid 0118 targetIconSize: root.currentCategory === EmojiModel.Custom ? Kirigami.Units.gridUnit * 3 : root.categoryIconSize // Custom emojis are bigger 0119 model: root.selectedType === 1 ? emoticonFilterModel : searchField.text.length === 0 ? EmojiModel.emojis(root.currentCategory) : (root.includeCustom ? EmojiModel.filterModel(searchField.text, false) : EmojiModel.filterModelNoCustom(searchField.text, false)) 0120 Layout.fillWidth: true 0121 Layout.fillHeight: true 0122 withCustom: root.includeCustom 0123 onChosen: unicode => root.chosen(unicode) 0124 header: categories 0125 Keys.forwardTo: searchField 0126 stickers: root.selectedType === 1 0127 onStickerChosen: stickerModel.postSticker(emoticonFilterModel.mapToSource(emoticonFilterModel.index(index, 0)).row) 0128 } 0129 0130 Kirigami.Separator { 0131 visible: showQuickReaction 0132 Layout.fillWidth: true 0133 Layout.preferredHeight: 1 0134 } 0135 0136 QQC2.ScrollView { 0137 visible: showQuickReaction 0138 Layout.fillWidth: true 0139 Layout.preferredHeight: root.categoryIconSize + QQC2.ScrollBar.horizontal.height 0140 QQC2.ScrollBar.horizontal.height: QQC2.ScrollBar.horizontal.visible ? QQC2.ScrollBar.horizontal.implicitHeight : 0 0141 0142 ListView { 0143 id: quickReactions 0144 Layout.fillWidth: true 0145 0146 model: ["👍", "👎", "😄", "🎉", "😕", "❤", "🚀", "👀"] 0147 0148 delegate: EmojiDelegate { 0149 emoji: modelData 0150 0151 height: root.categoryIconSize 0152 width: height 0153 0154 onClicked: root.chosen(modelData) 0155 } 0156 0157 orientation: Qt.Horizontal 0158 } 0159 } 0160 0161 ImagePacksModel { 0162 id: stickerPackModel 0163 room: root.currentRoom 0164 showStickers: true 0165 showEmoticons: false 0166 } 0167 0168 StickerModel { 0169 id: stickerModel 0170 model: stickerPackModel 0171 packIndex: 0 0172 room: root.currentRoom 0173 } 0174 0175 EmoticonFilterModel { 0176 id: emoticonFilterModel 0177 sourceModel: stickerModel 0178 showStickers: true 0179 } 0180 0181 Component { 0182 id: emojiDelegate 0183 Kirigami.NavigationTabButton { 0184 width: root.categoryIconSize 0185 height: width 0186 checked: categories.currentIndex === model.index 0187 text: modelData ? modelData.emoji : "" 0188 QQC2.ToolTip.text: modelData ? modelData.name : "" 0189 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay 0190 QQC2.ToolTip.visible: hovered 0191 onClicked: { 0192 categories.currentIndex = index; 0193 categories.focus = true; 0194 } 0195 } 0196 } 0197 0198 Component { 0199 id: stickerDelegate 0200 Kirigami.NavigationTabButton { 0201 width: root.categoryIconSize 0202 height: width 0203 checked: stickerModel.packIndex === model.index 0204 contentItem: Image { 0205 source: model.avatarUrl 0206 } 0207 QQC2.ToolTip.text: model.name 0208 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay 0209 QQC2.ToolTip.visible: hovered && !!model.name 0210 onClicked: stickerModel.packIndex = model.index 0211 } 0212 } 0213 0214 function clearSearchField() { 0215 searchField.text = ""; 0216 } 0217 }