mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-03-28 17:42:45 +01:00
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:
@@ -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');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user