import QtQuick import Quickshell import qs.Common import qs.Services import qs.Widgets import qs.Modules.Plugins PluginComponent { id: root property var pluginService: null // Load settings from PluginService property var enabledEmojis: pluginService ? pluginService.loadPluginData("exampleEmojiPlugin", "emojis", ["๐Ÿ˜Š", "๐Ÿ˜ข", "โค๏ธ"]) : ["๐Ÿ˜Š", "๐Ÿ˜ข", "โค๏ธ"] property int cycleInterval: pluginService ? pluginService.loadPluginData("exampleEmojiPlugin", "cycleInterval", 3000) : 3000 property int maxBarEmojis: pluginService ? pluginService.loadPluginData("exampleEmojiPlugin", "maxBarEmojis", 3) : 3 // Current state for cycling through emojis property int currentIndex: 0 property var displayedEmojis: [] // Timer to cycle through emojis at the configured interval Timer { interval: root.cycleInterval running: true repeat: true onTriggered: { if (root.enabledEmojis.length > 0) { root.currentIndex = (root.currentIndex + 1) % root.enabledEmojis.length root.updateDisplayedEmojis() } } } // Update the emojis shown in the bar when settings or index changes function updateDisplayedEmojis() { const maxToShow = Math.min(root.maxBarEmojis, root.enabledEmojis.length) let emojis = [] for (let i = 0; i < maxToShow; i++) { const idx = (root.currentIndex + i) % root.enabledEmojis.length emojis.push(root.enabledEmojis[idx]) } root.displayedEmojis = emojis } Component.onCompleted: { updateDisplayedEmojis() } onEnabledEmojisChanged: updateDisplayedEmojis() onMaxBarEmojisChanged: updateDisplayedEmojis() horizontalBarPill: Component { StyledRect { width: emojiRow.implicitWidth + Theme.spacingM * 2 height: parent.widgetThickness radius: Theme.cornerRadius color: Theme.surfaceContainerHigh Row { id: emojiRow anchors.centerIn: parent spacing: Theme.spacingXS Repeater { model: root.displayedEmojis StyledText { text: modelData font.pixelSize: Theme.fontSizeLarge } } } } } verticalBarPill: Component { StyledRect { width: parent.widgetThickness height: emojiColumn.implicitHeight + Theme.spacingM * 2 radius: Theme.cornerRadius color: Theme.surfaceContainerHigh Column { id: emojiColumn anchors.centerIn: parent spacing: Theme.spacingXS Repeater { model: root.displayedEmojis StyledText { text: modelData font.pixelSize: Theme.fontSizeMedium anchors.horizontalCenter: parent.horizontalCenter } } } } } popoutContent: Component { Item { width: parent.width height: parent.height // A grid of 120+ emojis for the user to pick from property var allEmojis: [ "๐Ÿ˜€", "๐Ÿ˜ƒ", "๐Ÿ˜„", "๐Ÿ˜", "๐Ÿ˜†", "๐Ÿ˜…", "๐Ÿคฃ", "๐Ÿ˜‚", "๐Ÿ™‚", "๐Ÿ™ƒ", "๐Ÿ˜‰", "๐Ÿ˜Š", "๐Ÿ˜‡", "๐Ÿฅฐ", "๐Ÿ˜", "๐Ÿคฉ", "๐Ÿ˜˜", "๐Ÿ˜—", "๐Ÿ˜š", "๐Ÿ˜™", "๐Ÿ˜‹", "๐Ÿ˜›", "๐Ÿ˜œ", "๐Ÿคช", "๐Ÿ˜", "๐Ÿค‘", "๐Ÿค—", "๐Ÿคญ", "๐Ÿคซ", "๐Ÿค”", "๐Ÿค", "๐Ÿคจ", "๐Ÿ˜", "๐Ÿ˜‘", "๐Ÿ˜ถ", "๐Ÿ˜", "๐Ÿ˜’", "๐Ÿ™„", "๐Ÿ˜ฌ", "๐Ÿคฅ", "๐Ÿ˜Œ", "๐Ÿ˜”", "๐Ÿ˜ช", "๐Ÿคค", "๐Ÿ˜ด", "๐Ÿ˜ท", "๐Ÿค’", "๐Ÿค•", "๐Ÿคข", "๐Ÿคฎ", "๐Ÿคง", "๐Ÿฅต", "๐Ÿฅถ", "๐Ÿ˜ถโ€๐ŸŒซ๏ธ", "๐Ÿ˜ต", "๐Ÿ˜ตโ€๐Ÿ’ซ", "๐Ÿคฏ", "๐Ÿค ", "๐Ÿฅณ", "๐Ÿ˜Ž", "๐Ÿค“", "๐Ÿง", "๐Ÿ˜•", "๐Ÿ˜Ÿ", "๐Ÿ™", "โ˜น๏ธ", "๐Ÿ˜ฎ", "๐Ÿ˜ฏ", "๐Ÿ˜ฒ", "๐Ÿ˜ณ", "๐Ÿฅบ", "๐Ÿ˜ฆ", "๐Ÿ˜ง", "๐Ÿ˜จ", "๐Ÿ˜ฐ", "๐Ÿ˜ฅ", "๐Ÿ˜ข", "๐Ÿ˜ญ", "๐Ÿ˜ฑ", "๐Ÿ˜–", "๐Ÿ˜ฃ", "๐Ÿ˜ž", "๐Ÿ˜“", "๐Ÿ˜ฉ", "๐Ÿ˜ซ", "๐Ÿฅฑ", "๐Ÿ˜ค", "๐Ÿ˜ก", "๐Ÿ˜ ", "๐Ÿคฌ", "โค๏ธ", "๐Ÿงก", "๐Ÿ’›", "๐Ÿ’š", "๐Ÿ’™", "๐Ÿ’œ", "๐Ÿ–ค", "๐Ÿค", "๐ŸคŽ", "๐Ÿ’”", "โค๏ธโ€๐Ÿ”ฅ", "โค๏ธโ€๐Ÿฉน", "๐Ÿ’•", "๐Ÿ’ž", "๐Ÿ’“", "๐Ÿ’—", "๐Ÿ’–", "๐Ÿ’˜", "๐Ÿ’", "๐Ÿ’Ÿ", "๐Ÿ‘", "๐Ÿ‘Ž", "๐Ÿ‘Š", "โœŠ", "๐Ÿค›", "๐Ÿคœ", "๐Ÿคž", "โœŒ๏ธ", "๐ŸคŸ", "๐Ÿค˜", "๐Ÿ‘Œ", "๐ŸคŒ", "๐Ÿค", "๐Ÿ‘ˆ", "๐Ÿ‘‰", "๐Ÿ‘†", "๐Ÿ‘‡", "โ˜๏ธ", "โœ‹", "๐Ÿคš" ] Column { anchors.fill: parent anchors.margins: Theme.spacingM spacing: Theme.spacingM StyledText { text: "Click an emoji to copy it!" font.pixelSize: Theme.fontSizeMedium font.weight: Font.Medium color: Theme.surfaceText } DankFlickable { width: parent.width height: parent.height - parent.spacing - 30 contentWidth: emojiGrid.width contentHeight: emojiGrid.height clip: true Grid { id: emojiGrid width: parent.width - Theme.spacingM columns: 8 spacing: Theme.spacingS Repeater { model: allEmojis StyledRect { width: 45 height: 45 radius: Theme.cornerRadius color: emojiMouseArea.containsMouse ? Theme.surfaceContainerHighest : Theme.surfaceContainerHigh border.width: 0 StyledText { anchors.centerIn: parent text: modelData font.pixelSize: Theme.fontSizeXLarge } MouseArea { id: emojiMouseArea anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { Quickshell.execDetached(["sh", "-c", "echo -n '" + modelData + "' | wl-copy"]) ToastService.show("Copied " + modelData + " to clipboard", 2000) root.closePopout() } } } } } } } } } popoutWidth: 400 popoutHeight: 500 }