Files
noctalia-shell/Modules/Panels/Launcher/Providers/EmojiProvider.qml
T
2026-01-28 14:41:55 -05:00

164 lines
4.7 KiB
QML

import QtQuick
import Quickshell
import qs.Commons
import qs.Services.Keyboard
Item {
id: root
// Provider metadata
property string name: I18n.tr("launcher.providers.emoji")
property var launcher: null
property string iconMode: Settings.data.appLauncher.iconMode
property bool handleSearch: false
property string supportedLayouts: "grid" // Only grid layout for emoji
property int preferredGridColumns: 7 // More columns for compact emoji display
property real preferredGridCellRatio: 1.15 // Slightly taller than wide to accommodate label
property bool supportsAutoPaste: true // Emoji can be auto-pasted
property string selectedCategory: "recent"
property bool showsCategories: true // Default to showing categories
// Empty state message for category view
readonly property string emptyBrowsingMessage: selectedCategory === "recent" ? I18n.tr("launcher.providers.emoji-no-recent") : ""
property var categoryIcons: ({
"all": "apps",
"recent": "clock",
"people": "user",
"animals": "paw",
"nature": "leaf",
"food": "apple",
"activity": "run",
"travel": "plane",
"objects": "home",
"symbols": "star",
"flags": "flag"
})
property var categories: ["all", "recent", "people", "animals", "nature", "food", "activity", "travel", "objects", "symbols", "flags"]
function getCategoryName(category) {
const names = {
"all": I18n.tr("launcher.categories.emoji-all"),
"recent": I18n.tr("launcher.categories.emoji-recent"),
"people": I18n.tr("launcher.categories.emoji-people"),
"animals": I18n.tr("launcher.categories.emoji-animals"),
"nature": I18n.tr("launcher.categories.emoji-nature"),
"food": I18n.tr("launcher.categories.emoji-food"),
"activity": I18n.tr("launcher.categories.emoji-activity"),
"travel": I18n.tr("launcher.categories.emoji-travel"),
"objects": I18n.tr("launcher.categories.emoji-objects"),
"symbols": I18n.tr("launcher.categories.emoji-symbols"),
"flags": I18n.tr("launcher.categories.emoji-flags")
};
return names[category] || category;
}
// Force update results when emoji service loads
Connections {
target: EmojiService
function onLoadedChanged() {
if (EmojiService.loaded && root.launcher) {
root.launcher.updateResults();
}
}
}
// Initialize provider
function init() {
Logger.d("EmojiProvider", "Initialized");
}
function selectCategory(category) {
selectedCategory = category;
if (launcher) {
launcher.updateResults();
}
}
function onOpened() {
// Always reset to "recent" category when opening
selectedCategory = "recent";
}
// Check if this provider handles the command
function handleCommand(searchText) {
return searchText.startsWith(">emoji");
}
// Return available commands when user types ">"
function commands() {
return [
{
"name": ">emoji",
"description": I18n.tr("launcher.providers.emoji-search-description"),
"icon": iconMode === "tabler" ? "mood-smile" : "face-smile",
"isTablerIcon": true,
"isImage": false,
"onActivate": function () {
launcher.setSearchText(">emoji ");
}
}
];
}
// Get search results
function getResults(searchText) {
if (!searchText.startsWith(">emoji")) {
return [];
}
if (!EmojiService.loaded) {
return [
{
"name": I18n.tr("launcher.providers.emoji-loading"),
"description": I18n.tr("launcher.providers.emoji-loading-description"),
"icon": iconMode === "tabler" ? "refresh" : "view-refresh",
"isTablerIcon": true,
"isImage": false,
"onActivate": function () {}
}
];
}
var query = searchText.slice(6).trim();
var emojis = [];
if (query !== "" || selectedCategory === "all") {
emojis = EmojiService.search(query);
} else {
emojis = EmojiService.getEmojisByCategory(selectedCategory);
}
}
// Format an emoji entry for the results list
function formatEmojiEntry(emoji) {
let title = emoji.name;
let description = emoji.keywords.join(", ");
if (emoji.category) {
description += " • Category: " + emoji.category;
}
const emojiChar = emoji.emoji;
return {
"name": title,
"description": description,
"icon": null,
"isImage": false,
"displayString": emojiChar,
"autoPasteText": emojiChar,
"provider": root,
"onAutoPaste": function () {
EmojiService.recordUsage(emojiChar);
},
"onActivate": function () {
EmojiService.copy(emojiChar);
launcher.close();
}
};
}
}