Feature: Add emoji picker for easy emoji insertion on desktop

Added a professional emoji picker widget to make it easier to insert emoji on desktop browsers where native emoji input is not readily available.

Changes:
- Added emoji-picker-element library from CDN (~50KB)
- New emoji button (😊) next to the Send button
- Full emoji picker with categories and search functionality
- Emoji inserted at cursor position in textarea
- Automatic byte counter update after insertion
- Mobile responsive: 6 columns on mobile, 8 on desktop
- Click outside to close picker

Benefits:
- Easy emoji access on Windows/Linux desktop browsers
- No need to use Win+. shortcut or copy-paste
- Professional UI with search and categories
- Still works with native emoji keyboards on mobile

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2025-12-21 20:57:44 +01:00
parent dd867c9fac
commit e879fec918
2 changed files with 118 additions and 12 deletions

View File

@@ -24,6 +24,9 @@ document.addEventListener('DOMContentLoaded', function() {
// Setup event listeners
setupEventListeners();
// Setup emoji picker
setupEmojiPicker();
// Load device status
loadStatus();
});
@@ -473,3 +476,58 @@ function escapeHtml(text) {
div.textContent = text;
return div.innerHTML;
}
/**
* Setup emoji picker
*/
function setupEmojiPicker() {
const emojiBtn = document.getElementById('emojiBtn');
const emojiPickerPopup = document.getElementById('emojiPickerPopup');
const messageInput = document.getElementById('messageInput');
if (!emojiBtn || !emojiPickerPopup || !messageInput) {
console.error('Emoji picker elements not found');
return;
}
// Create emoji-picker element
const picker = document.createElement('emoji-picker');
emojiPickerPopup.appendChild(picker);
// Toggle emoji picker on button click
emojiBtn.addEventListener('click', function(e) {
e.stopPropagation();
emojiPickerPopup.classList.toggle('hidden');
});
// Insert emoji into textarea when selected
picker.addEventListener('emoji-click', function(event) {
const emoji = event.detail.unicode;
const cursorPos = messageInput.selectionStart;
const textBefore = messageInput.value.substring(0, cursorPos);
const textAfter = messageInput.value.substring(messageInput.selectionEnd);
// Insert emoji at cursor position
messageInput.value = textBefore + emoji + textAfter;
// Update cursor position (after emoji)
const newCursorPos = cursorPos + emoji.length;
messageInput.setSelectionRange(newCursorPos, newCursorPos);
// Update character counter
updateCharCounter();
// Focus back on input
messageInput.focus();
// Hide picker after selection
emojiPickerPopup.classList.add('hidden');
});
// Close emoji picker when clicking outside
document.addEventListener('click', function(e) {
if (!emojiPickerPopup.contains(e.target) && e.target !== emojiBtn && !emojiBtn.contains(e.target)) {
emojiPickerPopup.classList.add('hidden');
}
});
}

View File

@@ -2,6 +2,47 @@
{% block title %}Chat - mc-webui{% endblock %}
{% block extra_head %}
<!-- Emoji Picker -->
<script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js"></script>
<style>
emoji-picker {
--emoji-size: 1.5rem;
--num-columns: 8;
}
.emoji-picker-container {
position: relative;
}
.emoji-picker-popup {
position: absolute;
bottom: 100%;
right: 0;
z-index: 1000;
margin-bottom: 0.5rem;
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
border-radius: 0.5rem;
overflow: hidden;
}
.emoji-picker-popup.hidden {
display: none;
}
/* Mobile responsive adjustments */
@media (max-width: 576px) {
emoji-picker {
--emoji-size: 1.25rem;
--num-columns: 6;
}
.emoji-picker-popup {
right: auto;
left: 0;
width: 100%;
max-width: 100%;
}
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid d-flex flex-column" style="height: 100%;">
<!-- Messages Container -->
@@ -25,18 +66,25 @@
<div class="row border-top bg-light">
<div class="col-12">
<form id="sendMessageForm" class="p-3">
<div class="input-group">
<textarea
id="messageInput"
class="form-control"
placeholder="Type a message..."
rows="2"
maxlength="500"
required
></textarea>
<button type="submit" class="btn btn-primary px-4" id="sendBtn">
<i class="bi bi-send"></i> Send
</button>
<div class="emoji-picker-container">
<div class="input-group">
<textarea
id="messageInput"
class="form-control"
placeholder="Type a message..."
rows="2"
maxlength="500"
required
></textarea>
<button type="button" class="btn btn-outline-secondary" id="emojiBtn" title="Insert emoji">
<i class="bi bi-emoji-smile"></i>
</button>
<button type="submit" class="btn btn-primary px-4" id="sendBtn">
<i class="bi bi-send"></i> Send
</button>
</div>
<!-- Emoji picker popup (hidden by default) -->
<div id="emojiPickerPopup" class="emoji-picker-popup hidden"></div>
</div>
<div class="d-flex justify-content-between">
<small class="text-muted">Shift+Enter: new line, Enter: send</small>