mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-25 21:40:49 +02:00
Add full emoji library with improved display and prominent invisible text button
This commit is contained in:
+381
-1
@@ -179,6 +179,214 @@ textarea {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
/* Special styling for encoded message textarea */
|
||||
.output-section textarea {
|
||||
background-color: var(--secondary-bg);
|
||||
color: var(--accent-color);
|
||||
border: 1px solid rgba(100, 181, 246, 0.3);
|
||||
border-radius: 6px;
|
||||
font-family: 'Fira Code', monospace;
|
||||
letter-spacing: 0.5px;
|
||||
line-height: 1.5;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
padding: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Emoji Library Styling */
|
||||
.emoji-library {
|
||||
margin: 16px 0;
|
||||
background-color: var(--main-bg-color);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
border: 1px solid var(--input-border);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.emoji-library-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid var(--input-border);
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.emoji-library-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.emoji-library-title i {
|
||||
margin-right: 8px;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.emoji-library-subtitle {
|
||||
font-size: 0.8rem;
|
||||
font-weight: normal;
|
||||
opacity: 0.7;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.emoji-search {
|
||||
position: relative;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.emoji-search input {
|
||||
width: 100%;
|
||||
padding: 8px 12px 8px 32px;
|
||||
background-color: var(--input-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-color);
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.emoji-search input:focus {
|
||||
border-color: var(--accent-color);
|
||||
box-shadow: 0 0 0 2px rgba(var(--accent-color-rgb), 0.2);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.emoji-search i {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--text-color);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.emoji-grid-wrapper {
|
||||
border-radius: 6px;
|
||||
background-color: var(--secondary-bg);
|
||||
padding: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.emoji-grid-note {
|
||||
background-color: rgba(var(--accent-color-rgb), 0.1);
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.emoji-grid-note i {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.emoji-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(42px, 1fr));
|
||||
gap: 10px;
|
||||
max-height: 250px;
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
scrollbar-width: thin;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--input-border);
|
||||
}
|
||||
|
||||
.emoji-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
font-size: 1.25rem;
|
||||
background-color: var(--button-bg);
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
padding: 0;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.emoji-button:hover {
|
||||
background-color: var(--button-hover-bg);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.emoji-button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Emoji Library Footer */
|
||||
.emoji-library-footer {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid var(--input-border);
|
||||
}
|
||||
|
||||
.selected-emoji-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.selected-emoji {
|
||||
font-size: 1.5rem;
|
||||
padding: 4px 8px;
|
||||
background-color: var(--secondary-bg);
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--input-border);
|
||||
}
|
||||
|
||||
.selected-emoji-label {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.emoji-button.selected {
|
||||
background-color: var(--accent-color);
|
||||
color: var(--main-bg-color);
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.emoji-category-tabs {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.emoji-category-tab {
|
||||
padding: 6px 12px;
|
||||
background-color: var(--button-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-color);
|
||||
font-size: 0.8rem;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.emoji-category-tab.active {
|
||||
background-color: var(--accent-color);
|
||||
color: var(--main-bg-color);
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
|
||||
textarea::placeholder {
|
||||
color: rgba(224, 224, 224, 0.5);
|
||||
}
|
||||
@@ -199,6 +407,43 @@ button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
/* Invisible Text Button */
|
||||
.invisible-button {
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
background-color: var(--secondary-bg);
|
||||
border: 2px dashed var(--accent-color);
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.invisible-button .carrier-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.invisible-button .carrier-emoji {
|
||||
font-size: 1.5rem;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.invisible-button:hover {
|
||||
background-color: rgba(var(--accent-color-rgb), 0.1);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.invisible-button.active {
|
||||
background-color: var(--accent-color);
|
||||
color: var(--main-bg-color);
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var(--button-bg);
|
||||
color: var(--text-color);
|
||||
@@ -261,6 +506,52 @@ button:hover {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* Carrier styling */
|
||||
.carrier-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.carrier-emoji {
|
||||
font-size: 1.5rem;
|
||||
line-height: 1;
|
||||
display: block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.carrier-name {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Preview styling */
|
||||
.transform-preview {
|
||||
margin-top: auto;
|
||||
width: 100%;
|
||||
font-size: 0.7rem;
|
||||
padding: 4px;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 3px;
|
||||
white-space: normal;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.preview-label {
|
||||
color: var(--accent-color);
|
||||
opacity: 0.8;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.preview-ellipsis {
|
||||
color: var(--accent-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Encoded preview styling */
|
||||
.encoded-preview {
|
||||
display: inline-block;
|
||||
@@ -341,21 +632,110 @@ button:hover {
|
||||
background: var(--button-bg);
|
||||
color: var(--text-color);
|
||||
transition: all 0.2s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.transform-button:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.transform-button:hover {
|
||||
background: var(--button-hover-bg);
|
||||
color: var(--main-bg-color);
|
||||
border-color: var(--accent-color);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.transform-button:hover:before {
|
||||
border-color: var(--accent-color);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.transform-button.active {
|
||||
background: var(--button-active-bg);
|
||||
color: var(--main-bg-color);
|
||||
border-color: var(--button-active-bg);
|
||||
box-shadow: 0 2px 12px rgba(100, 181, 246, 0.3);
|
||||
}
|
||||
|
||||
.transform-button.active:before {
|
||||
border-color: var(--accent-color);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Add a subtle indicator for clickable buttons */
|
||||
.transform-button:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
background: var(--accent-color);
|
||||
opacity: 0;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.transform-button.active:after {
|
||||
opacity: 0.8;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
/* Output section */
|
||||
.output-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
margin-top: 16px;
|
||||
padding: 16px;
|
||||
background: var(--main-bg-color);
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--accent-color);
|
||||
box-shadow: 0 2px 12px rgba(100, 181, 246, 0.15);
|
||||
}
|
||||
|
||||
.output-heading h4 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--success-color);
|
||||
margin-bottom: 8px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.output-heading h4 small {
|
||||
color: var(--accent-color);
|
||||
font-size: 0.8rem;
|
||||
margin-left: 8px;
|
||||
font-weight: normal;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.output-instructions {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-color);
|
||||
opacity: 0.7;
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.output-instructions i {
|
||||
color: var(--accent-color);
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.output-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
+57
-12
@@ -79,32 +79,76 @@
|
||||
@click="selectCarrier(carrier)"
|
||||
:title="carrier.desc"
|
||||
>
|
||||
{{ carrier.emoji }} {{ carrier.name }}
|
||||
<div class="carrier-content">
|
||||
<span class="carrier-emoji">{{ carrier.emoji }}</span>
|
||||
<span class="carrier-name">{{ carrier.name }}</span>
|
||||
</div>
|
||||
<small class="transform-preview" v-if="emojiMessage">
|
||||
<span class="preview-label">Preview:</span>
|
||||
<span class="encoded-preview">{{ carrier.preview ? carrier.preview(emojiMessage.slice(0, 10)) : '' }}</span>
|
||||
<span class="preview-ellipsis" v-if="emojiMessage.length > 10">...</span>
|
||||
</small>
|
||||
</button>
|
||||
<button
|
||||
class="transform-button"
|
||||
:class="{ active: activeSteg === 'invisible' }"
|
||||
@click="setStegMode('invisible')"
|
||||
title="Make text invisible using zero-width characters"
|
||||
>
|
||||
<i class="fas fa-eye-slash"></i> Invisible
|
||||
<small class="transform-preview" v-if="emojiMessage">
|
||||
{{ previewInvisible(emojiMessage.slice(0, 10)) }}
|
||||
</small>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Big Invisible Text Button -->
|
||||
<button
|
||||
class="transform-button invisible-button"
|
||||
:class="{ active: activeSteg === 'invisible' }"
|
||||
@click="setStegMode('invisible')"
|
||||
title="Make text invisible using zero-width characters"
|
||||
>
|
||||
<div class="carrier-content">
|
||||
<span class="carrier-emoji"><i class="fas fa-eye-slash"></i></span>
|
||||
<span class="carrier-name">Invisible Text Mode</span>
|
||||
</div>
|
||||
<small class="transform-preview" v-if="emojiMessage">
|
||||
<span class="preview-label">Preview:</span>
|
||||
<span class="encoded-preview">{{ previewInvisible(emojiMessage.slice(0, 10)) }}</span>
|
||||
<span class="preview-ellipsis" v-if="emojiMessage.length > 10">...</span>
|
||||
</small>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Emoji Library Section -->
|
||||
<div class="emoji-library">
|
||||
<div class="emoji-library-header">
|
||||
<div class="emoji-library-title">
|
||||
<i class="fas fa-icons"></i> Quick Emoji Picker
|
||||
<span class="emoji-library-subtitle">Click any emoji to insert it at cursor position</span>
|
||||
</div>
|
||||
<div class="emoji-search">
|
||||
<i class="fas fa-search"></i>
|
||||
<input type="text" placeholder="Search emojis..." v-model="emojiSearch" @input="filterEmojis">
|
||||
</div>
|
||||
</div>
|
||||
<div id="emoji-grid-container" class="emoji-grid-wrapper"></div>
|
||||
<div class="emoji-library-footer" v-if="selectedEmoji">
|
||||
<div class="selected-emoji-info">
|
||||
<span class="selected-emoji">{{ selectedEmoji }}</span>
|
||||
<span class="selected-emoji-label">Last selected</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output-section" v-if="encodedMessage">
|
||||
<div class="output-heading">
|
||||
<h4>
|
||||
<i class="fas fa-check-circle"></i>
|
||||
Encoded Message
|
||||
<small v-if="selectedCarrier">using {{ selectedCarrier.name }}</small>
|
||||
<small v-else-if="activeSteg === 'invisible'">using Invisible Text</small>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="output-container">
|
||||
<textarea readonly v-model="encodedMessage"></textarea>
|
||||
<button class="copy-button" @click="copyToClipboard(encodedMessage)" title="Copy to clipboard">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="output-instructions">
|
||||
<small><i class="fas fa-info-circle"></i> Copy this text and share it. Only people who know how to decode it will be able to read your message.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="decode-section" v-if="showDecoder">
|
||||
@@ -179,6 +223,7 @@
|
||||
|
||||
<script src="js/transforms.js"></script>
|
||||
<script src="js/steganography.js"></script>
|
||||
<script src="js/emojiLibrary.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -26,7 +26,11 @@ new Vue({
|
||||
selectedCarrier: null,
|
||||
activeSteg: null,
|
||||
carriers: window.steganography.carriers,
|
||||
showDecoder: true
|
||||
showDecoder: true,
|
||||
// Emoji Library
|
||||
emojiSearch: '',
|
||||
filteredEmojis: [...window.emojiLibrary.EMOJI_LIST],
|
||||
selectedEmoji: null
|
||||
},
|
||||
methods: {
|
||||
// Theme Toggle
|
||||
@@ -52,13 +56,29 @@ new Vue({
|
||||
|
||||
// Steganography Methods
|
||||
selectCarrier(carrier) {
|
||||
this.selectedCarrier = carrier;
|
||||
this.activeSteg = 'emoji';
|
||||
this.autoEncode();
|
||||
// Toggle carrier selection if clicking the same one again
|
||||
if (this.selectedCarrier === carrier) {
|
||||
this.selectedCarrier = null;
|
||||
this.encodedMessage = '';
|
||||
} else {
|
||||
this.selectedCarrier = carrier;
|
||||
this.activeSteg = 'emoji';
|
||||
this.autoEncode();
|
||||
}
|
||||
},
|
||||
setStegMode(mode) {
|
||||
this.activeSteg = mode;
|
||||
this.autoEncode();
|
||||
// Toggle mode selection if clicking the same one again
|
||||
if (this.activeSteg === mode) {
|
||||
this.activeSteg = null;
|
||||
this.encodedMessage = '';
|
||||
} else {
|
||||
this.activeSteg = mode;
|
||||
// When switching to invisible mode, clear the carrier selection
|
||||
if (mode === 'invisible') {
|
||||
this.selectedCarrier = null;
|
||||
}
|
||||
this.autoEncode();
|
||||
}
|
||||
},
|
||||
autoEncode() {
|
||||
if (!this.emojiMessage) {
|
||||
@@ -249,13 +269,67 @@ new Vue({
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
// Emoji Library Methods
|
||||
filterEmojis() {
|
||||
if (!this.emojiSearch) {
|
||||
this.filteredEmojis = [...window.emojiLibrary.EMOJI_LIST];
|
||||
this.renderEmojiGrid();
|
||||
return;
|
||||
}
|
||||
|
||||
const searchTerm = this.emojiSearch.toLowerCase();
|
||||
this.filteredEmojis = window.emojiLibrary.EMOJI_LIST.filter(emoji => {
|
||||
// Simple search - we could enhance this with emoji names/descriptions later
|
||||
return emoji.toLowerCase().includes(searchTerm);
|
||||
});
|
||||
|
||||
this.renderEmojiGrid();
|
||||
},
|
||||
|
||||
selectEmoji(emoji) {
|
||||
this.selectedEmoji = emoji;
|
||||
|
||||
// Insert the emoji at cursor position in the textarea
|
||||
const textarea = document.getElementById('steg-input');
|
||||
if (textarea) {
|
||||
const startPos = textarea.selectionStart;
|
||||
const endPos = textarea.selectionEnd;
|
||||
const currentValue = this.emojiMessage;
|
||||
|
||||
// Insert emoji at cursor position
|
||||
this.emojiMessage = currentValue.substring(0, startPos) + emoji + currentValue.substring(endPos);
|
||||
|
||||
// Set cursor position after the inserted emoji
|
||||
this.$nextTick(() => {
|
||||
textarea.focus();
|
||||
textarea.selectionStart = startPos + emoji.length;
|
||||
textarea.selectionEnd = startPos + emoji.length;
|
||||
|
||||
// Trigger encoding
|
||||
this.autoEncode();
|
||||
});
|
||||
|
||||
this.showNotification(`Emoji ${emoji} inserted`);
|
||||
}
|
||||
},
|
||||
|
||||
renderEmojiGrid() {
|
||||
window.emojiLibrary.renderEmojiGrid('emoji-grid-container', this.selectEmoji.bind(this), this.filteredEmojis);
|
||||
}
|
||||
},
|
||||
// Initialize theme
|
||||
// Initialize theme and components
|
||||
mounted() {
|
||||
// Apply theme
|
||||
if (this.isDarkTheme) {
|
||||
document.body.classList.add('dark-theme');
|
||||
}
|
||||
|
||||
// Initialize emoji grid
|
||||
this.$nextTick(() => {
|
||||
this.renderEmojiGrid();
|
||||
});
|
||||
},
|
||||
// Keyboard shortcuts
|
||||
created() {
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
// Emoji Library for P4RS3LT0NGV3
|
||||
|
||||
// Create namespace for emoji library
|
||||
window.emojiLibrary = {};
|
||||
|
||||
// Make emoji list globally available
|
||||
window.emojiLibrary.EMOJI_LIST = [
|
||||
// Faces and People
|
||||
"😀", // Grinning Face
|
||||
"😂", // Face with Tears of Joy
|
||||
"🥰", // Smiling Face with Hearts
|
||||
"😎", // Smiling Face with Sunglasses
|
||||
"🤔", // Thinking Face
|
||||
"😅", // Smiling Face with Sweat
|
||||
"😊", // Smiling Face with Smiling Eyes
|
||||
"😇", // Smiling Face with Halo
|
||||
"🙃", // Upside-Down Face
|
||||
"😉", // Winking Face
|
||||
"🥳", // Partying Face
|
||||
"😴", // Sleeping Face
|
||||
"🥱", // Yawning Face
|
||||
"🤯", // Exploding Head
|
||||
"🧠", // Brain
|
||||
|
||||
// Gestures and Body Parts
|
||||
"👍", // Thumbs Up
|
||||
"👎", // Thumbs Down
|
||||
"👏", // Clapping Hands
|
||||
"🤝", // Handshake
|
||||
"👋", // Waving Hand
|
||||
"✌️", // Victory Hand
|
||||
"🤟", // Love-You Gesture
|
||||
"👀", // Eyes
|
||||
"👁️", // Eye
|
||||
"🧿", // Nazar Amulet
|
||||
|
||||
// Celebration & Objects
|
||||
"🎉", // Party Popper
|
||||
"🎂", // Birthday Cake
|
||||
"🎁", // Wrapped Gift
|
||||
"🏆", // Trophy
|
||||
"🏅", // Sports Medal
|
||||
"💰", // Money Bag
|
||||
"💸", // Money with Wings
|
||||
"💯", // Hundred Points
|
||||
"📱", // Mobile Phone
|
||||
"💻", // Laptop
|
||||
"⌨️", // Keyboard
|
||||
"🔒", // Locked
|
||||
"🔓", // Unlocked
|
||||
|
||||
// Food & Drink
|
||||
"🍕", // Pizza
|
||||
"🍔", // Hamburger
|
||||
"🍦", // Ice Cream
|
||||
"🍩", // Doughnut
|
||||
"🍺", // Beer Mug
|
||||
"🍷", // Wine Glass
|
||||
"☕", // Hot Beverage
|
||||
|
||||
// Nature & Weather
|
||||
"🌈", // Rainbow
|
||||
"🌞", // Sun with Face
|
||||
"🌙", // Crescent Moon
|
||||
"⭐", // Star
|
||||
"🌟", // Glowing Star
|
||||
"⚡", // High Voltage
|
||||
"❄️", // Snowflake
|
||||
"🔥", // Fire
|
||||
"💧", // Droplet
|
||||
"🌊", // Water Wave
|
||||
|
||||
// Animals
|
||||
"🐱", // Cat Face
|
||||
"🐶", // Dog Face
|
||||
"🦊", // Fox
|
||||
"🐼", // Panda
|
||||
"🦁", // Lion
|
||||
"🐬", // Dolphin
|
||||
"🦄", // Unicorn
|
||||
|
||||
// Symbols & Special
|
||||
"❤️", // Red Heart
|
||||
"🧡", // Orange Heart
|
||||
"💚", // Green Heart
|
||||
"💙", // Blue Heart
|
||||
"💜", // Purple Heart
|
||||
"🚀", // Rocket
|
||||
"👀", // Eyes
|
||||
"💀", // Skull
|
||||
"🥹", // Face Holding Back Tears
|
||||
"🐍", // Snake
|
||||
"🐉", // Dragon
|
||||
"🐲", // Dragon Face
|
||||
"🧙♂️", // Wizard
|
||||
"🪄", // Magic Wand
|
||||
"🏴☠️", // Pirate Flag
|
||||
"🦅", // Eagle (often associated with pirates)
|
||||
"🦜", // Parrot (pirate symbol)
|
||||
"💻", // Laptop (hacker symbol)
|
||||
"🕶️", // Sunglasses (cool guy symbol)
|
||||
"🧑💻", // Technologist
|
||||
"👨💻", // Man Technologist
|
||||
"👩💻", // Woman Technologist
|
||||
"🕵️", // Detective
|
||||
"🕵️♂️", // Man Detective
|
||||
"🕵️♀️", // Woman Detective
|
||||
"🖥️", // Desktop Computer
|
||||
"⌨️", // Keyboard
|
||||
"🖱️", // Computer Mouse
|
||||
"🕹️", // Joystick
|
||||
"📱", // Mobile Phone
|
||||
"📲", // Mobile Phone with Arrow
|
||||
"🔓", // Unlocked (hacker symbol)
|
||||
"🔑", // Key (hacker symbol)
|
||||
"🗝️", // Old Key (hacker symbol)
|
||||
"🛡️", // Shield (hacker symbol)
|
||||
"⚔️", // Crossed Swords (hacker symbol)
|
||||
"🧬", // DNA (hacker symbol)
|
||||
"🧫", // Petri Dish (hacker symbol)
|
||||
"🧪", // Test Tube (hacker symbol)
|
||||
"🛠️", // Hammer and Wrench (hacker symbol)
|
||||
"⚙️", // Gear (hacker symbol)
|
||||
"🧰", // Toolbox (hacker symbol)
|
||||
"🧲", // Magnet (hacker symbol)
|
||||
"💣", // Bomb (hacker symbol)
|
||||
"🕳️", // Hole (hacker symbol)
|
||||
"📡", // Satellite Antenna (hacker symbol)
|
||||
"🛰️", // Satellite (hacker symbol)
|
||||
"📞", // Telephone Receiver (hacker symbol)
|
||||
"☎️", // Telephone (hacker symbol)
|
||||
"📟", // Pager (hacker symbol)
|
||||
"📠", // Fax Machine (hacker symbol)
|
||||
"🔌", // Electric Plug (hacker symbol)
|
||||
"💡", // Light Bulb (hacker symbol)
|
||||
"🔦", // Flashlight (hacker symbol)
|
||||
"🕯️", // Candle (hacker symbol)
|
||||
"🗞️", // Rolled-Up Newspaper (hacker symbol)
|
||||
"📜", // Scroll (hacker symbol)
|
||||
"📃", // Page with Curl (hacker symbol)
|
||||
"📄", // Page Facing Up (hacker symbol)
|
||||
"📑", // Bookmark Tabs (hacker symbol)
|
||||
"📊", // Bar Chart (hacker symbol)
|
||||
"📈", // Chart Increasing (hacker symbol)
|
||||
"📉", // Chart Decreasing (hacker symbol)
|
||||
"🗂️", // Card Index Dividers (hacker symbol)
|
||||
"🗃️", // Card File Box (hacker symbol)
|
||||
"🗄️", // File Cabinet (hacker symbol)
|
||||
"🗑️", // Wastebasket (hacker symbol)
|
||||
"🛢️", // Oil Drum (hacker symbol)
|
||||
"🛎️", // Bellhop Bell (hacker symbol)
|
||||
"🧳", // Luggage (hacker symbol)
|
||||
"🛌", // Person in Bed (hacker symbol)
|
||||
"🛏️", // Bed (hacker symbol)
|
||||
"🛋️", // Couch and Lamp (hacker symbol)
|
||||
"🪑", // Chair (hacker symbol)
|
||||
"🚪", // Door (hacker symbol)
|
||||
"🧴", // Lotion Bottle (hacker symbol)
|
||||
"🧷", // Safety Pin (hacker symbol)
|
||||
"🧹", // Broom (hacker symbol)
|
||||
"🧺", // Basket (hacker symbol)
|
||||
"🧻", // Roll of Paper (hacker symbol)
|
||||
"🧼", // Soap (hacker symbol)
|
||||
"🧽", // Sponge (hacker symbol)
|
||||
"🧯", // Fire Extinguisher (hacker symbol)
|
||||
"🛒", // Shopping Cart (hacker symbol)
|
||||
"🚬", // Cigarette (hacker symbol)
|
||||
"⚰️", // Coffin (hacker symbol)
|
||||
"⚱️", // Funeral Urn (hacker symbol)
|
||||
"🗿", // Moai (hacker symbol)
|
||||
"🛂", // Passport Control (hacker symbol)
|
||||
"🛃", // Customs (hacker symbol)
|
||||
"🛄", // Baggage Claim (hacker symbol)
|
||||
"🛅", // Left Luggage (hacker symbol)
|
||||
"🚹", // Men's Room (hacker symbol)
|
||||
"🚺", // Women's Room (hacker symbol)
|
||||
"🚼", // Baby Symbol (hacker symbol)
|
||||
"🚻", // Restroom (hacker symbol)
|
||||
"🚮", // Litter in Bin Sign (hacker symbol)
|
||||
"🚰", // Potable Water (hacker symbol)
|
||||
"🚾", // Water Closet (hacker symbol)
|
||||
"🚭", // No Smoking (hacker symbol)
|
||||
"🚯", // No Littering (hacker symbol)
|
||||
"🚱", // Non-Potable Water (hacker symbol)
|
||||
];
|
||||
|
||||
// Function to render emoji grid
|
||||
window.emojiLibrary.renderEmojiGrid = function(containerId, onEmojiSelect, filteredList) {
|
||||
const container = document.getElementById(containerId);
|
||||
if (!container) return;
|
||||
|
||||
// Clear container
|
||||
container.innerHTML = '';
|
||||
|
||||
// Create emoji grid
|
||||
const gridContainer = document.createElement('div');
|
||||
gridContainer.className = 'emoji-grid';
|
||||
|
||||
// Set a heading explaining the full library is shown
|
||||
if (!filteredList || filteredList.length === window.emojiLibrary.EMOJI_LIST.length) {
|
||||
const fullLibraryNote = document.createElement('div');
|
||||
fullLibraryNote.className = 'emoji-grid-note';
|
||||
fullLibraryNote.innerHTML = '<i class="fas fa-info-circle"></i> Showing all emojis. Use search to filter.';
|
||||
container.appendChild(fullLibraryNote);
|
||||
}
|
||||
|
||||
// Determine which list to use (filtered or full)
|
||||
const emojisToShow = filteredList || window.emojiLibrary.EMOJI_LIST;
|
||||
|
||||
// Add emojis to grid
|
||||
emojisToShow.forEach(emoji => {
|
||||
const emojiButton = document.createElement('button');
|
||||
emojiButton.className = 'emoji-button';
|
||||
emojiButton.innerHTML = emoji;
|
||||
emojiButton.title = 'Click to select this emoji';
|
||||
emojiButton.addEventListener('click', () => {
|
||||
if (typeof onEmojiSelect === 'function') {
|
||||
onEmojiSelect(emoji);
|
||||
}
|
||||
});
|
||||
|
||||
gridContainer.appendChild(emojiButton);
|
||||
});
|
||||
|
||||
container.appendChild(gridContainer);
|
||||
};
|
||||
Reference in New Issue
Block a user