From cd2b57b27df08c6e56247897f0303a353ae1375b Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 16 Feb 2026 16:36:18 +0000 Subject: [PATCH] emote autoroles --- api/emotes.php | 139 ++++++ assets/css/discord.css | 42 ++ assets/js/main.js | 543 ++++++++++++++------- assets/pasted-20260216-132213-80b79cbe.png | Bin 0 -> 68168 bytes assets/pasted-20260216-162915-c3590120.png | Bin 0 -> 23279 bytes db/migrations/001_create_custom_emotes.sql | 7 + index.php | 69 ++- requests.log | 25 + 8 files changed, 654 insertions(+), 171 deletions(-) create mode 100644 api/emotes.php create mode 100644 assets/pasted-20260216-132213-80b79cbe.png create mode 100644 assets/pasted-20260216-162915-c3590120.png create mode 100644 db/migrations/001_create_custom_emotes.sql diff --git a/api/emotes.php b/api/emotes.php new file mode 100644 index 0000000..b02f439 --- /dev/null +++ b/api/emotes.php @@ -0,0 +1,139 @@ +query("SELECT * FROM custom_emotes ORDER BY created_at DESC"); + echo json_encode(['success' => true, 'emotes' => $stmt->fetchAll()]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; +} + +if ($action === 'upload' && $_SERVER['REQUEST_METHOD'] === 'POST') { + if (!isset($_FILES['emote'])) { + echo json_encode(['success' => false, 'error' => 'Aucun fichier reçu (emote)']); + exit; + } + + if ($_FILES['emote']['error'] !== UPLOAD_ERR_OK) { + $errorMsg = 'Erreur d\'upload PHP: ' . $_FILES['emote']['error']; + if ($_FILES['emote']['error'] === 1) $errorMsg = 'Fichier trop volumineux (limit PHP)'; + if ($_FILES['emote']['error'] === 4) $errorMsg = 'Aucun fichier sélectionné'; + echo json_encode(['success' => false, 'error' => $errorMsg]); + exit; + } + + $name = preg_replace('/[^a-z0-9_]/', '', strtolower($_POST['name'] ?? 'emote')); + if (empty($name)) { + echo json_encode(['success' => false, 'error' => 'Nom invalide']); + exit; + } + + $file = $_FILES['emote']; + $ext = pathinfo($file['name'], PATHINFO_EXTENSION); + if (!in_array(strtolower($ext), ['png', 'jpg', 'jpeg'])) { + echo json_encode(['success' => false, 'error' => 'Format non supporté (PNG uniquement recommandé)']); + exit; + } + + $uploadDir = __DIR__ . '/../assets/images/custom_emotes/'; + if (!is_dir($uploadDir)) { + mkdir($uploadDir, 0775, true); + } + + $fileName = time() . '_' . $name . '.png'; + $targetPath = $uploadDir . $fileName; + + // Process image: Resize to 48x48 + $srcImage = null; + if (strtolower($ext) === 'png') $srcImage = imagecreatefrompng($file['tmp_name']); + else if (in_array(strtolower($ext), ['jpg', 'jpeg'])) $srcImage = imagecreatefromjpeg($file['tmp_name']); + + if (!$srcImage) { + echo json_encode(['success' => false, 'error' => 'Fichier image corrompu']); + exit; + } + + $width = imagesx($srcImage); + $height = imagesy($srcImage); + $newSize = 48; + $dstImage = imagecreatetruecolor($newSize, $newSize); + + // Transparency for PNG + imagealphablending($dstImage, false); + imagesavealpha($dstImage, true); + $transparent = imagecolorallocatealpha($dstImage, 255, 255, 255, 127); + imagefilledrectangle($dstImage, 0, 0, $newSize, $newSize, $transparent); + + imagecopyresampled($dstImage, $srcImage, 0, 0, 0, 0, $newSize, $newSize, $width, $height); + imagepng($dstImage, $targetPath); + + imagedestroy($srcImage); + imagedestroy($dstImage); + + $relativePath = 'assets/images/custom_emotes/' . $fileName; + $code = ':' . $name . ':'; + + try { + $stmt = db()->prepare("INSERT INTO custom_emotes (name, path, code) VALUES (?, ?, ?)"); + $stmt->execute([$name, $relativePath, $code]); + echo json_encode([ + 'success' => true, + 'emote' => [ + 'id' => db()->lastInsertId(), + 'name' => $name, + 'path' => $relativePath, + 'code' => $code + ] + ]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; +} + +if ($action === 'rename' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $id = $_POST['id'] ?? 0; + $newName = preg_replace('/[^a-z0-9_]/', '', strtolower($_POST['name'] ?? '')); + if (empty($newName)) { + echo json_encode(['success' => false, 'error' => 'Nom invalide']); + exit; + } + + try { + $code = ':' . $newName . ':'; + $stmt = db()->prepare("UPDATE custom_emotes SET name = ?, code = ? WHERE id = ?"); + $stmt->execute([$newName, $code, $id]); + echo json_encode(['success' => true, 'name' => $newName, 'code' => $code]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; +} + +if ($action === 'delete' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $id = $_POST['id'] ?? 0; + try { + $stmt = db()->prepare("SELECT path FROM custom_emotes WHERE id = ?"); + $stmt->execute([$id]); + $emote = $stmt->fetch(); + if ($emote) { + $filePath = __DIR__ . '/../' . $emote['path']; + if (file_exists($filePath)) unlink($filePath); + + $stmt = db()->prepare("DELETE FROM custom_emotes WHERE id = ?"); + $stmt->execute([$id]); + echo json_encode(['success' => true]); + } else { + echo json_encode(['success' => false, 'error' => 'Emote non trouvée']); + } + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; +} diff --git a/assets/css/discord.css b/assets/css/discord.css index 92e2995..04dfcd1 100644 --- a/assets/css/discord.css +++ b/assets/css/discord.css @@ -872,6 +872,48 @@ body { border-left: 2px solid var(--blurple); } +/* Emotes Tab in Settings */ +#settings-emotes-sidebar button { + border-radius: 4px; + transition: background-color 0.2s, color 0.2s; + color: var(--text-muted) !important; +} + +#settings-emotes-sidebar button:hover { + background-color: var(--hover) !important; + color: var(--text-primary) !important; +} + +#settings-emotes-sidebar button.active { + background-color: var(--active) !important; + color: white !important; +} + +.role-emoji-item { + transition: transform 0.1s, background-color 0.2s; + border: 1px solid transparent; +} + +.role-emoji-item:hover { + transform: scale(1.2); + background-color: rgba(255, 255, 255, 0.1) !important; + border-color: var(--blurple); + z-index: 1; +} + +.role-emoji-item img { + max-width: 100%; + max-height: 100%; + object-fit: contain; +} + +#custom-emote-upload-zone .btn { + display: flex; + align-items: center; + gap: 5px; + font-weight: 600; +} + .pinned-badge { font-size: 0.7em; color: var(--blurple); diff --git a/assets/js/main.js b/assets/js/main.js index 2449f47..67fc062 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -32,30 +32,221 @@ document.addEventListener('DOMContentLoaded', () => { 'Smileys': ['😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '😚', '😙', '😋', '😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭', '🤫', '🤔', '🤐', '🤨', '😐', '😑', '😶', '😏', '😒', '🙄', '😬', '🤥', '😌', '😔', '😪', '🤤', '😴', '😷', '🤒', '🤕', '🤢', '🤮', '🤧', '🥵', '🥶', '🥴', '😵', '🤯', '🤠', '🥳', '😎', '🤓', '🧐', '😕', '😟', '🙁', '☹️', '😮', '😯', '😲', '😳', '🥺', '😦', '😧', '😨', '😰', '😥', '😢', '😭', '😱', '😖', '😣', '😞', '😓', '😩', '😫', '🥱', '😤', '😡', '😠', '🤬', '😈', '👿', '👹', '👺', '💀', '☠️', '💩', '🤡', '👻', '👽', '👾', '🤖', '😺', '😸', '😻', '😼', '😽', '🙀', '😿', '😾', '🙈', '🙉', '🙊', '💋', '💌', '💘', '💝', '💖', '💗', '💓', '💞', '💕', '💟', '❣️', '💔', '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💯', '💢', '💥', '💫', '💦', '💨', '🕳️', '💣', '💬', '👁️‍🗨️', '🗨️', '🗯️', '💭', '💤', '🪐', '🌠', '🎇', '🎆', '🌇', '🌆', '🏙️', '🌃', '🌌'], 'Gestures': ['👋', '🤚', '🖐️', '✋', '🖖', '👌', '🤏', '✌️', '🤞', '🤟', '🤘', '🤙', '👈', '👉', '👆', '🖕', '👇', '☝️', '👍', '👎', '✊', '👊', '🤛', '🤜', '👏', '🙌', '👐', '🤲', '🤝', '🙏', '✍️', '💅', '🤳', '💪', '🦾', '🦵', '🦿', '🦶', '👂', '🦻', '👃', '🧠', '🦷', '🦴', '👀', '👁️', '👅', '👄', '🖖', '🤘', '🤙', '🖐️', '🖕', '🖖', '✍️', '🤳', '💪', '🦾'], 'People': ['👶', '🧒', '👦', '👧', '🧑', '👱', '👨', '👩', '🧓', '👴', '👵', '👮', '🕵️', '💂', '👷', '🤴', '👸', '👳', '👲', '🧕', '🤵', '👰', '🤰', '🤱', '👼', '🎅', '🤶', '🦸', '🦹', '🧙', '🧚', '🧛', '🧜', '🧝', '🧞', '🧟', '💆', '💇', '🚶', '🏃', '💃', '🕺', '🕴️', '👯', '🧖', '🧗', '🤺', '🏇', '⛷️', '🏂', '🏌️', '🏄', '🚣', '🏊', '⛹️', '🏋️', '🚴', '🚵', '🤸', '🤼', '🤽', '🤾', '🤹', '🧘', '🛀', '🛌'], - 'Animals': ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯', '🦁', '🐮', '🐷', '🐽', '🐸', '🐵', '🙈', '🙉', '🙊', '🐒', '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🦆', '🦅', '🦉', '🦇', '🐺', '🐗', '🐴', '🦄', '🐝', '🐛', '🦋', '🐌', '🐞', '🐜', '🦟', '🦗', '🕷️', '🕸️', '🦂', '🐢', '🐍', '🦎', '🦖', '🦕', '🐙', '🦑', '🦐', '🦞', '🦀', '🐡', '🐠', '🐟', '🐬', '🐳', '🐋', '🦈', '🐊', '🐅', '🐆', '🦓', '🦍', '🦧', '🐘', '🦛', '🦏', '🐪', '🐫', '🦒', '🦘', '🦬', '🐃', '🐂', '🐄', '🐎', '🐖', '🐏', '🐑', '🐐', '🦌', '🐕', '🐩', '🦮', '🐕‍🦺', '🐈', '🐈‍⬛', '🐓', '🦃', '🦚', '🦜', '🦢', '🦩', '🕊️', '🐇', '🦝', '🦨', '🦡', '🦦', '🦥', '🐁', '🐀', '🐿️', '🦔', '🐾', '🐉', '🐲', '🌵', '🎄', '🌲', '🌳', '🌴', '🌱', '🌿', '☘️', '🍀', '🎍', '🎋', '🍃', '🍂', '🍁', '🍄', '🐚', '🌾'], + 'Animals': ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯', '🦁', '🐮', '🐷', '🐽', '🐸', '🐵', '🙈', '🙉', '🙊', '🐒', '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🦆', '🦅', '🦉', '🦇', '🐺', '🐗', '🐴', '🦄', '🐝', '🐛', '🦋', '🐌', '🐞', '🐜', '🦟', '🦗', '🕷️', '🕸️', '蠍', '🐢', '🐍', '🦎', '🦖', '🦕', '🐙', '🦑', '🦐', '🦞', '🦀', '🐡', '🐠', '🐟', '🐬', '🐳', '🐋', '🦈', '🐊', '🐅', '🐆', '🦓', '🦍', '🦧', '🐘', '🦛', '🦏', '🐪', '🐫', '🦒', '🦘', '🦬', '🐃', '🐂', '🐄', '🐎', '🐖', '🐏', '🐑', '🐐', '🦌', '🐕', '🐩', '🦮', '🐕‍🦺', '🐈', '🐈‍⬛', '🐓', '🦃', '🦚', '🦜', '🦢', '🦩', '🕊️', '🐇', '🦝', '🦨', '🦡', '🦦', '🦥', '🐁', '🐀', '🐿️', '🦔', '🐾', '🐉', '🐲', '🌵', '🎄', '🌲', '🌳', '🌴', '🌱', '🌿', '☘️', '🍀', '🎍', '🎋', '🍃', '🍂', '🍁', '🍄', '🐚', '🌾'], 'Nature': ['💐', '🌷', '🌹', '🥀', '🌺', '🌸', '🌼', '🌻', '🌞', '🌝', '🌛', '🌜', '🌚', '🌕', '🌖', '🌗', '🌘', '🌑', '🌒', '🌓', '🌔', '🌙', '🌎', '🌍', '🌏', '🪐', '💫', '⭐️', '🌟', '✨', '⚡️', '☄️', '💥', '🔥', '🌪️', '🌈', '☀️', '🌤️', '⛅️', '🌥️', '☁️', '🌦️', '🌧️', '🌨️', '🌩️', '❄️', '☃️', '⛄️', '🌬️', '💨', '💧', '💦', '☔️', '☂️', '🌊', '🌫️', '⛰️', '🏔️', '🗻', '🌋', '🏜️', '🏖️', '🏝️', '🏕️', '⛺️'], - 'Food': ['🍏', '🍎', '🍐', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🍈', '🍒', '🍑', '🥭', '🍍', '🥥', '🥝', '🍅', '🍆', '🥑', '🥦', '🥬', '🥒', '🌽', '🥕', '🧄', '🧅', '🍄', '🥜', '🌰', '🍞', '🥐', '🥖', '🥨', '🥯', '🥞', '🧇', '🧀', '🍖', '🍗', '🥩', '🥓', '🍔', '🍟', '🍕', '🌭', '🥪', '🌮', '🌯', '🥙', '🧆', '🍳', '🥘', '🍲', '🥣', '🥗', '🍿', '🧈', '🧂', '🥫', '🍱', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍠', '🍢', '🍣', '🍤', '🍥', '🥮', '🍡', '🥟', '🥠', '🥡', '🍦', '🍧', '🍨', '🍩', '🍪', '🎂', '🍰', '🧁', '🥧', '🍫', '🍬', '🍭', '🍮', '🍯', '🍼', '🥛', '☕️', '🍵', '🧉', '🥤', '🧃', '🍺', '🍻', '🥂', '🍷', '🥃', '🍸', '🍹', '🍾', '🧊', '🥄', '🍴', '🍽️'], - 'Activities': ['⚽️', '🏀', '🏈', '⚾️', '🥎', '🎾', '🏐', '🏉', '🎱', '🏓', '🏸', '🥅', '🏒', '🏑', '🏏', '⛳️', '🏹', '🎣', '🥊', '🥋', '🛹', '🛷', '⛸️', '🥌', '🎿', '⛷️', '🏂', '🏋️', '🤺', '🤼', '🤸', '⛹️', '🤽', '🤾', '🤹', '🧘', '🏇', '🚣', '🏊', '🚴', '🚵', '🧗', '🎖️', '🏆', '🏅', '🥇', '🥈', '🥉', '🎫', '🎟️', '🎭', '🎨', '🎬', '🎤', '🎧', '🎼', '🎹', '🥁', '🎷', '🎺', '🎸', '🪕', '🎻', '🎲', '♟️', '🎯', '🎳', '🎮', '🎰', '🧩'], - 'Travel': ['🚗', '🚕', '🚙', '🚌', '🚎', '🏎️', '🚓', '🚑', '🚒', '🚐', '🚚', '🚛', '🚜', '🛵', '🚲', '🛴', '🚏', '🛣️', '🛤️', '⛽️', '🚨', '🚥', '🚦', '🚧', '⚓️', '⛵️', '🚤', '🛳️', '⛴️', '🚢', '✈️', '🛫', '🛬', '💺', '🚁', '🚟', '🚠', '🚡', '🚀', '🛸', '🛰️', '⌛️', '⏳', '⌚️', '⏰', '⏱️', '⏲️', '🕰️', '🌡️', '🌃', '🏙️', '🌄', '🌅', '🌆', '🌇', '🌉', '🎠', '🎡', '🎢', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚝', '🚞', '🚋'], - 'Objects': ['⌚️', '📱', '📲', '💻', '⌨️', '🖱️', '🖲️', '🕹️', '🗜️', '💽', '💾', '💿', '📀', '📼', '📷', '📸', '📹', '🎥', '📽️', '🎞️', '📞', '📠', '📺', '📻', '🎙️', '🎚️', '🎛️', '🧭', '⏱️', '⏲️', '⏰', '🕰️', '⌛️', '⏳', '📡', '🔋', '🔌', '💡', '🔦', '🕯️', '🪔', '🧯', '🛢️', '💸', '💵', '💴', '💶', '💷', '💰', '💳', '💎', '⚖️', '🧰', '🔧', '🔨', '⚒️', '🛠️', '⛏️', '🔩', '⚙️', '🧱', '⛓️', '🧲', '🔫', '💣', '🧨', '🪓', '🔪', '🗡️', '⚔️', '🛡️', '🚬', '⚰️', '⚱️', '🏺', '🔮', '🧿', '📿', '💈', '⚗️', '🔭', '🔬', '🕳️', '💊', '💉', '🩸', '🧬', '🦠', '🧫', '🧪', '🌡️', '🧹', '🧺', '🧻', '🧼', '🧽', '🪒', '🧴', '🛎️', '🔑', '🗝️', '🚪', '🪑', '🛋️', '🛏️', '🛌', '🧸', '🖼️', '🛍️', '🛒', '🎁', '🎈', '🎏', '🎀', '🎊', '🎉', '🎎', '🏮', '🎐', '🧧', '✉️', '📩', '📨', '📧', '💌', '📥', '📤', '📦', '🏷️', '📁', '📂', '📅', '📆', '🗒️', '🗓️', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '🖇️', '📏', '📐', '✂️', '🗃️', '🗄️', '🗑️', '🔒', '🔓', '🔏', '🔐', '🔑', '🗝️'], - 'Symbols': ['💘', '💝', '💖', '💗', '💓', '💞', '💕', '💟', '❣️', '💔', '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💯', '💢', '💥', '💫', '💦', '💨', '🕳️', '💣', '💬', '👁️‍🗨️', '🗨️', '🗯️', '💭', '💤', '🌐', '♠️', '♥️', '♦️', '♣️', '🃏', '🀄️', '🎴', '🔇', '🔈', '🔉', '🔊', '📢', '📣', '📯', '🔔', '🔕', '🎼', '🎵', '🎶', '💹', '🏧', '🚮', '🚰', '♿️', '🚹', '🚺', '🚻', '🚼', '🚾', '🛂', '🛃', '🛄', '🛅', '⚠️', '🚸', '⛔️', '🚫', '🚳', '🚭', '🚯', '🚱', '🚷', '📵', '🔞', '☢️', '☣️', '⬆️', '↗️', '➡️', '↘️', '⬇️', '↙️', '⬅️', '↖️', '↕️', '↔️', '↩️', '↪️', '⤴️', '⤵️', '🔃', '🔄', '🔙', '🔚', '🔛', '🔜', '🔝', '🛐', '⚛️', '🕉️', '✡️', '☸️', '☯️', '✝️', '☦️', '☪️', '☮️', '🕎', '🔯', '♈️', '♉️', '♊️', '♋️', '♌️', '♍️', '♎️', '♏️', '♐️', '♑️', '♒️', '♓️', '⛎', '🔀', '🔁', '🔂', '▶️', '⏩', '⏭️', '⏯️', '◀️', '⏪', '⏮️', '🔼', '⏫', '🔽', '⏬', '⏸️', '⏹️', '⏺️', '⏏️', '🎦', '🔅', '🔆', '📶', '📳', '📴', '➕', '➖', '➗', '✖️', '♾️', '‼️', '⁉️', '❓', '❔', '❕', '❗️', '〰️', '💱', '💲', '⚕️', '♻️', '⚜️', '🔱', '📛', '🔰', '⭕️', '✅', '☑️', '✔️', '✖️', '❌', '❎', '➰', '➿', '〽️', '✳️', '✴️', '❇️', '‼️', '🈁', '🈂️', '🈷️', '🈶', '🈯️', '🉐', '🈹', '🈚️', '🈲', '🉑', '🈸', '🈴', '🈳', '㊗️', '㊙️', '🈺', '🈵', '🔴', '🟠', '🟡', '🟢', '🔵', '🟣', '🟤', '⚫️', '⚪️', '🟥', '🟧', '🟨', '🟩', '🟦', '🟪', '🟫', '⬛️', '⬜️', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '⛎', '☸', '☦', '☦', '☪', '☮', '☯', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '⛎', '♀', '♂', '⚕', '♾', '⚓', '⚔', '⚖', '⚗', '⚙', '⚖', '⚓', '⚔'], + 'Food': ['🍏', '🍎', '🍐', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🍈', '🍒', '🍑', '🥭', '🍍', '🥥', '🥝', '🍅', '🍆', '🥑', '🥦', '🥬', '🥒', '🌽', '🥕', '🧄', '🧅', '🍄', '🥜', '🌰', '🍞', '🥐', '🥖', '🥨', '🥯', '🥞', '🧇', '🧀', '🍖', '🍗', '🥩', '🥓', '🍔', '🍟', '🍕', '🌭', '🥪', '🌮', '🌯', '🥙', '🧆', '🍳', '🥘', '🍲', '🥣', '🥗', '🍿', 'バター', '🧂', '🥫', '🍱', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍠', '🍢', '🍣', '🍤', '🍥', '🥮', '🍡', '🥟', '🥠', '🥡', '🍦', '🍧', '🍨', '🍩', '🍪', '🎂', '🍰', '🧁', '🥧', '🍫', '🍬', '🍭', '🍮', '🍯', '🍼', '🥛', '☕️', '🍵', '🧉', '🥤', '🧃', '🍺', '🍻', '🥂', '🍷', '🥃', '🍸', '🍹', '🍾', '🧊', '🥄', '🍴', '🍽️'], + 'Activities': ['⚽️', '🏀', '🏈', '⚾️', '🥎', '🎾', '🏐', '🏉', '🎱', '🏓', '🏸', '🥅', '🏒', '🏑', '🏏', '⛳️', '🏹', '🎣', '🥊', '🥋', '🛹', '🛷', '⛸️', '🥌', '🎿', '⛷️', '🏂', '🏋️', '🤺', '🤼', '🤸', '⛹️', '🤽', '🤾', '🤹', '🧘', '🏇', '🚣', '🏊', '🚴', '🚵', '🧗', '🎖️', '🏆', '🏅', '🥇', '🥈', '🥉', '🎫', '🎟️', '🎭', '🎨', '🎬', '🎤', '🎧', '🎼', '🎹', '🥁', '🎷', '🎺', '🎸', '🪕', '🎻', '🎲', '♟️', '🎯', 'コツ', '🎮', '🎰', '🧩'], + 'Travel': ['🚗', '🚕', '🚙', '🚌', '🚎', '🏎️', '🚓', '🚑', '🚒', '🚐', '🚚', '🚛', '🚜', '🛵', '🚲', '🛴', '🚏', '🛣️', '🛤️', '⛽️', '🚨', '🚥', '🚦', '🚧', '⚓️', '⛵️', '🚤', '🛳️', '⛴️', '🚢', '✈️', '🛫', '🛬', '💺', '🚁', '🚟', 'ケーブル', '🚡', '🚀', '🛸', '🛰️', '⌛️', '⏳', '⌚️', '⏰', '⏱️', '⏲️', '🕰️', '🌡️', '🌃', '🏙️', '🌄', '🌅', '🌆', '🌇', '🌉', '🎠', '🎡', '🎢', '🚂', '🚃', '🚄', '🚅', '🚆', '🚇', '🚈', '🚉', '🚊', '🚝', '🚞', '🚋'], + 'Objects': ['⌚️', '📱', '📲', '💻', '⌨️', '🖱️', '🖲️', '🕹️', '🗜️', '💽', '💾', '💿', '📀', '📼', '📷', '📸', '📹', '🎥', '📽️', '🎞️', '📞', '📠', '📺', '📻', '🎙️', '🎚️', '🎛️', '🧭', '⏱️', '⏲️', '⏰', '🕰️', '⌛️', '⏳', '📡', '🔋', 'プラグ', '💡', '🔦', '🕯️', '🪔', '🧯', '🛢️', '💸', '💵', '💴', '💶', '💷', '💰', '💳', '💎', '⚖️', '🧰', 'レンチ', '🔨', '⚒️', '🛠️', '⛏️', 'ナット', '⚙️', '🧱', '鎖', '🧲', '🔫', '💣', '🧨', '🪓', 'ナイフ', '🗡️', '⚔️', '盾', '🚬', '⚰️', '⚱️', '🏺', '水晶', '🧿', '📿', '💈', '⚗️', '望遠鏡', '🔬', '🕳️', '💊', '💉', '🩸', 'DNA', '🦠', '🧫', '🧪', '🌡️', '🧹', 'カゴ', '🧻', '石鹸', 'スポンジ', '🪒', 'ローション', '🛎️', '鍵', '🗝️', 'ドア', '椅子', 'ソファ', 'ベッド', '🛌', 'テディベア', '額縁', '袋', 'カート', '🎁', '🎈', '🎏', 'リボン', '🎊', '🎉', '人形', '提灯', '🎐', '🧧', '✉️', '📩', '📨', '📧', '💌', '📥', '📤', '📦', '🏷️', 'フォルダ', '📂', 'カレンダー', '📆', '🗒️', '🗓️', '📇', 'チャート', '📉', '📊', 'クリップボード', '画鋲', '📍', '📎', '🖇️', '定規', '📐', 'ハサミ', '🗃️', 'キャビネット', 'ゴミ箱', '🔒', '🔓', '🔏', '🔐', '鍵', '🗝️'], + 'Symbols': ['💘', '💝', '💖', '💗', '💓', '💞', '💕', '💟', '❣️', '💔', '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💯', '💢', '💥', '💫', '💦', '💨', '🕳️', '💣', '💬', '👁️‍🗨️', '🗨️', '🗯️', '💭', '💤', '🌐', '♠️', '♥️', '♦️', '♣️', 'ジョーカー', '🀄️', '🎴', '🔇', '🔈', '🔉', '🔊', '📢', '📣', '📯', '🔔', '🔕', '🎼', '🎵', '🎶', '💹', 'ATM', '🚮', '🚰', '♿️', '🚹', '🚺', '🚻', '🚼', '🚾', '🛂', 'カスタム', 'バゲージ', '🛅', '⚠️', '🚸', '⛔️', '🚫', '🚳', '🚯', '🚱', '🚷', '📵', '🔞', '放射能', 'バイオ', '⬆️', '↗️', '➡️', '↘️', '⬇️', '↙️', '⬅️', '↖️', '↕️', '↔️', '↩️', '↪️', '⤴️', '⤵️', '🔃', '🔄', '🔙', '🔚', '🔛', '🔜', '🔝', '🛐', '⚛️', '🕉️', '✡️', '☸️', '☯️', '✝️', '☦️', '☪️', '☮️', '🕎', '🔯', '♈️', '♉️', '♊️', '♋️', '♌️', '♍️', '♎️', '♏️', '♐️', '♑️', '♒️', '♓️', '⛎', '🔀', '🔁', '🔂', '▶️', '⏩', '⏭️', '⏯️', '◀️', '⏪', '⏮️', '🔼', '⏫', '🔽', '⏬', '⏸️', '⏹️', '⏺️', '⏏️', '🎦', '🔅', '🔆', '📶', '📳', '📴', '➕', '➖', '➗', '✖️', '♾️', '‼️', '⁉️', '❓', '❔', '❕', '❗️', '〰️', '💱', '💲', '⚕️', '♻️', '⚜️', '🔱', '📛', '🔰', '⭕️', '✅', '☑️', '✔️', '✖️', '❌', '❎', '➰', '➿', '〽️', '✳️', '✴️', '❇️', '‼️', '🈁', '🈂️', '🈷️', '🈶', '🈯️', '🉐', '🈹', '🈚️', '🈲', '🉑', '🈸', '🈴', '🈳', '㊗️', '㊙️', '🈺', '🈵', '🔴', '🟠', '🟡', '🟢', '🔵', '🟣', '🟤', '⚫️', '⚪️', '🟥', '🟧', '🟨', '🟩', '🟦', '🟪', '🟫', '⬛️', '⬜️', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '⛎', '☸', '☦', '☦', '☪', '☮', '☯', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '⛎', '♀', '♂', '⚕', '♾', '⚓', '⚔', '⚖', '⚗', '⚙', '⚖', '⚓', '⚔'], 'Flags': ['🏁', '🚩', '🎌', '🏴', '🏳️', '🏳️‍🌈', '🏳️‍⚧️', '🏴‍☠️', '🇦🇫', '🇦🇽', '🇦🇱', '🇩🇿', '🇦🇲', '🇦🇺', '🇦🇹', '🇦🇿', '🇧🇪', '🇧🇷', '🇨🇦', '🇨🇱', '🇨🇳', '🇨🇴', '🇨🇿', '🇩🇰', '🇪🇬', '🇫🇮', '🇫🇷', '🇩🇪', '🇬🇷', '🇭🇰', '🇮🇳', '🇮🇩', '🇮🇪', '🇮🇱', '🇮🇹', '🇯🇵', '🇰🇷', '🇲🇽', '🇳🇱', '🇳🇿', '🇳🇴', '🇵🇰', '🇵🇭', '🇵🇱', '🇵🇹', '🇷🇺', '🇸🇦', '🇸🇬', '🇿🇦', '🇪🇸', '🇸🇪', '🇨🇭', '🇹🇭', '🇹🇷', '🇺🇦', '🇦🇪', '🇬🇧', '🇺🇸', '🇻🇳', '🇦🇷', '🇧🇩', '🇧🇪', '🇧🇴', '🇮🇩', '🇮🇷', '🇮🇶', '🇯🇲', '🇰🇿', '🇰🇪', '🇲🇾', '🇲🇦', '🇳🇬', '🇵🇪', '🇷🇴', '🇷🇸', '🇸🇰', '🇺🇾', '🇿🇼'] }; + const categoryIcons = { + 'Custom': '⭐', + 'Smileys': '😀', + 'Gestures': '👌', + 'People': '👶', + 'Animals': '🐶', + 'Nature': '🌵', + 'Food': '🍏', + 'Activities': '⚽️', + 'Travel': '🚗', + 'Objects': '⌚️', + 'Symbols': '❤️', + 'Flags': '🏁' + }; + const ALL_EMOJIS = Object.values(EMOJI_CATEGORIES).flat(); + // Unified custom emote loading and caching + window.CUSTOM_EMOTES_CACHE = []; + window.loadCustomEmotes = async () => { + try { + const resp = await fetch('api/emotes.php?action=list'); + const data = await resp.json(); + if (data.success) { + window.CUSTOM_EMOTES_CACHE = data.emotes || []; + return window.CUSTOM_EMOTES_CACHE; + } + return []; + } catch (e) { + console.error("Failed to load custom emotes", e); + return []; + } + }; + + // Settings Emotes Tab Logic + async function setupSettingsEmotes() { + console.log("Setting up Emotes Tab..."); + const sidebar = document.getElementById('settings-emotes-sidebar'); + const grid = document.getElementById('settings-emotes-grid'); + const searchInput = document.getElementById('settings-emotes-search'); + const uploadZone = document.getElementById('custom-emote-upload-zone'); + const uploadInput = document.getElementById('emote-upload-input'); + + if (!sidebar || !grid) return; + + const categories = ['Custom', ...Object.keys(EMOJI_CATEGORIES)]; + + const renderGrid = async (category, searchTerm = '') => { + grid.innerHTML = '
'; + + if (category === 'Custom' && !searchTerm) { + if (uploadZone) uploadZone.classList.remove('d-none'); + const emotes = await window.loadCustomEmotes(); + grid.innerHTML = ''; + + if (emotes.length === 0) { + grid.innerHTML = '
Aucune emote personnalisée. Ajoutez-en une !
'; + } else { + emotes.forEach(emote => { + const div = document.createElement('div'); + div.className = 'role-emoji-item rounded d-flex flex-column align-items-center justify-content-center p-2 text-center position-relative'; + div.style.cursor = 'pointer'; + div.style.backgroundColor = 'rgba(255,255,255,0.05)'; + div.style.minHeight = '70px'; + div.innerHTML = ` + + ${emote.code} +
+ + +
+ `; + + div.onmouseenter = () => div.querySelector('.emote-actions')?.classList.remove('d-none'); + div.onmouseleave = () => div.querySelector('.emote-actions')?.classList.add('d-none'); + + div.onclick = (e) => { + if (e.target.closest('.emote-actions')) return; + navigator.clipboard.writeText(emote.code); + const originalBg = div.style.backgroundColor; + div.style.backgroundColor = 'var(--blurple)'; + setTimeout(() => div.style.backgroundColor = originalBg, 200); + }; + + div.querySelector('.delete-emote').onclick = async (e) => { + e.stopPropagation(); + if (!confirm(`Supprimer l'emote ${emote.code} ?`)) return; + const fd = new FormData(); + fd.append('id', emote.id); + const res = await (await fetch('api/emotes.php?action=delete', { method: 'POST', body: fd })).json(); + if (res.success) renderGrid('Custom'); + }; + + div.querySelector('.edit-emote').onclick = async (e) => { + e.stopPropagation(); + const newName = prompt("Nouveau nom (sans les :)", emote.name); + if (!newName || newName === emote.name) return; + const fd = new FormData(); + fd.append('id', emote.id); + fd.append('name', newName); + const res = await (await fetch('api/emotes.php?action=rename', { method: 'POST', body: fd })).json(); + if (res.success) renderGrid('Custom'); + }; + + grid.appendChild(div); + }); + } + } else { + if (uploadZone) uploadZone.classList.add('d-none'); + grid.innerHTML = ''; + const list = searchTerm ? ALL_EMOJIS.filter(e => e.includes(searchTerm)) : EMOJI_CATEGORIES[category]; + + (list || []).forEach(emoji => { + const div = document.createElement('div'); + div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-2'; + div.style.cursor = 'pointer'; + div.style.fontSize = '24px'; + div.style.backgroundColor = 'rgba(255,255,255,0.05)'; + div.textContent = emoji; + div.onclick = () => { + navigator.clipboard.writeText(emoji); + const originalBg = div.style.backgroundColor; + div.style.backgroundColor = 'var(--blurple)'; + setTimeout(() => div.style.backgroundColor = originalBg, 200); + }; + grid.appendChild(div); + }); + } + }; + + sidebar.innerHTML = ''; + categories.forEach((cat, idx) => { + const btn = document.createElement('button'); + btn.className = `btn w-100 text-start text-white border-0 py-2 px-3 mb-1 d-flex align-items-center gap-2 ${idx === 0 ? 'active' : ''}`; + btn.style.backgroundColor = idx === 0 ? 'rgba(255,255,255,0.1)' : 'transparent'; + btn.style.fontSize = '0.9em'; + btn.innerHTML = `${categoryIcons[cat] || '❓'} ${cat}`; + btn.onclick = () => { + sidebar.querySelectorAll('button').forEach(b => { + b.classList.remove('active'); + b.style.backgroundColor = 'transparent'; + }); + btn.classList.add('active'); + btn.style.backgroundColor = 'rgba(255,255,255,0.1)'; + if (searchInput) searchInput.value = ''; + renderGrid(cat); + }; + sidebar.appendChild(btn); + }); + + if (uploadInput) { + uploadInput.onchange = async () => { + const file = uploadInput.files[0]; + if (!file) return; + const name = prompt("Nom de l'emote:", file.name.split('.')[0]); + if (!name) return; + const fd = new FormData(); + fd.append('emote', file); + fd.append('name', name); + const res = await (await fetch('api/emotes.php?action=upload', { method: 'POST', body: fd })).json(); + if (res.success) { + renderGrid('Custom'); + window.loadCustomEmotes(); + } else alert(res.error); + uploadInput.value = ''; + }; + } + + if (searchInput) { + searchInput.oninput = () => { + const term = searchInput.value.trim(); + if (term) { + sidebar.querySelectorAll('button').forEach(b => { + b.classList.remove('active'); + b.style.backgroundColor = 'transparent'; + }); + renderGrid(null, term); + } else { + const activeBtn = sidebar.querySelector('button.active'); + renderGrid(activeBtn ? activeBtn.querySelector('span:last-child').textContent : 'Custom'); + } + }; + } + + renderGrid('Custom'); + } + + // Call when tab is shown + const emotesTabBtn = document.getElementById('emotes-tab-btn'); + if (emotesTabBtn) { + emotesTabBtn.addEventListener('shown.bs.tab', setupSettingsEmotes); + } + /** * Centralized Emoji Picker Component */ const UniversalEmojiPicker = { currentPicker: null, - show(anchor, callback, options = {}) { + async show(anchor, callback, options = {}) { this.hide(); const picker = document.createElement('div'); picker.className = 'emoji-picker p-0 overflow-hidden d-flex flex-column'; - picker.style.width = options.width || '450px'; + picker.style.width = options.width || '350px'; picker.style.height = options.height || '450px'; picker.style.backgroundColor = '#313338'; picker.style.border = '1px solid #1e1f22'; @@ -89,77 +280,113 @@ document.addEventListener('DOMContentLoaded', () => { grid.style.gap = '5px'; grid.style.backgroundColor = '#313338'; - const renderGrid = (cat = null, term = '') => { + const renderGrid = async (cat = null, term = '') => { grid.innerHTML = ''; - let list = term ? ALL_EMOJIS.filter(e => e.includes(term)) : EMOJI_CATEGORIES[cat]; - (list || []).forEach(emoji => { - const span = document.createElement('span'); - span.textContent = emoji; - span.className = 'emoji-item rounded d-flex align-items-center justify-content-center'; - span.style.cursor = 'pointer'; - span.style.fontSize = '24px'; - span.style.padding = '8px'; - span.style.aspectRatio = '1/1'; + if (term) { + const customEmotes = window.CUSTOM_EMOTES_CACHE || []; + const filteredCustom = customEmotes.filter(e => e.name.toLowerCase().includes(term.toLowerCase()) || e.code.toLowerCase().includes(term.toLowerCase())); - span.onclick = (e) => { + filteredCustom.forEach(emote => { + const div = document.createElement('div'); + div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-2'; + div.style.cursor = 'pointer'; + div.innerHTML = ``; + div.title = emote.code; + div.onclick = (e) => { + e.stopPropagation(); + callback(emote.code); + if (!options.keepOpen) this.hide(); + }; + grid.appendChild(div); + }); + + const filteredStandard = ALL_EMOJIS.filter(e => e.includes(term)); + filteredStandard.forEach(emoji => { + const div = document.createElement('div'); + div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-2'; + div.style.cursor = 'pointer'; + div.style.fontSize = '24px'; + div.textContent = emoji; + div.onclick = (e) => { + e.stopPropagation(); + callback(emoji); + if (!options.keepOpen) this.hide(); + }; + grid.appendChild(div); + }); + return; + } + + if (cat === 'Custom') { + const customEmotes = (window.CUSTOM_EMOTES_CACHE && window.CUSTOM_EMOTES_CACHE.length > 0) ? window.CUSTOM_EMOTES_CACHE : await window.loadCustomEmotes(); + if (customEmotes.length === 0) { + grid.innerHTML = '
Aucune emote personnalisée.
'; + return; + } + customEmotes.forEach(emote => { + const div = document.createElement('div'); + div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-2'; + div.style.cursor = 'pointer'; + div.innerHTML = ``; + div.title = emote.code; + div.onclick = (e) => { + e.stopPropagation(); + callback(emote.code); + if (!options.keepOpen) this.hide(); + }; + grid.appendChild(div); + }); + return; + } + + let list = EMOJI_CATEGORIES[cat]; + (list || []).forEach(emoji => { + const div = document.createElement('div'); + div.className = 'role-emoji-item rounded d-flex align-items-center justify-content-center p-2'; + div.style.cursor = 'pointer'; + div.style.fontSize = '24px'; + div.textContent = emoji; + div.onclick = (e) => { e.stopPropagation(); callback(emoji); if (!options.keepOpen) this.hide(); }; - grid.appendChild(span); + grid.appendChild(div); }); }; - // Init Tabs - const categoryIcons = { - 'Smileys': '😀', - 'Gestures': '👌', - 'People': '👶', - 'Animals': '🐶', - 'Nature': '🌵', - 'Food': '🍏', - 'Activities': '⚽️', - 'Travel': '🚗', - 'Objects': '⌚️', - 'Symbols': '❤️', - 'Flags': '🏁' - }; - - Object.keys(EMOJI_CATEGORIES).forEach((cat, idx) => { + const cats = ['Custom', ...Object.keys(EMOJI_CATEGORIES)]; + cats.forEach((cat, idx) => { const btn = document.createElement('button'); - btn.className = `btn btn-sm text-nowrap px-2 py-2 border-0 ${idx === 0 ? 'btn-primary' : 'btn-dark'}`; - btn.style.fontSize = '1.2em'; + btn.className = `btn btn-sm text-white border-0 p-2 ${idx === 0 ? 'active' : ''}`; + btn.style.backgroundColor = idx === 0 ? 'rgba(255,255,255,0.1)' : 'transparent'; + btn.innerHTML = categoryIcons[cat] || '❓'; btn.title = cat; - btn.textContent = categoryIcons[cat] || '❓'; - btn.onclick = (e) => { - e.stopPropagation(); - searchInput.value = ''; + btn.onclick = async () => { tabs.querySelectorAll('button').forEach(b => { - b.classList.remove('btn-primary'); - b.classList.add('btn-dark'); + b.classList.remove('active'); + b.style.backgroundColor = 'transparent'; }); - btn.classList.add('btn-primary'); - btn.classList.remove('btn-dark'); - renderGrid(cat); - }; - tabs.appendChild(btn); - }); - btn.classList.add('btn-primary'); - btn.classList.remove('btn-dark'); - renderGrid(cat); + btn.classList.add('active'); + btn.style.backgroundColor = 'rgba(255,255,255,0.1)'; + await renderGrid(cat); }; tabs.appendChild(btn); }); - searchInput.oninput = () => { + searchInput.oninput = async () => { const term = searchInput.value.trim(); if (term) { - tabs.querySelectorAll('button').forEach(b => b.classList.replace('btn-primary', 'btn-dark')); - renderGrid(null, term); + tabs.querySelectorAll('button').forEach(b => { + b.classList.remove('active'); + b.style.backgroundColor = 'transparent'; + }); + await renderGrid(null, term); } else { - const activeCat = tabs.querySelector('button.btn-primary')?.textContent || Object.keys(EMOJI_CATEGORIES)[0]; - renderGrid(activeCat); + const activeBtn = tabs.querySelector('button.active'); + const activeCat = activeBtn ? activeBtn.title : 'Custom'; + await renderGrid(activeCat); } }; @@ -180,7 +407,7 @@ document.addEventListener('DOMContentLoaded', () => { picker.style.top = `${top}px`; picker.style.left = `${left}px`; - renderGrid(Object.keys(EMOJI_CATEGORIES)[0]); + await renderGrid('Custom'); // Handle outside click const outsideClick = (e) => { @@ -203,45 +430,83 @@ document.addEventListener('DOMContentLoaded', () => { // Replace old showEmojiPicker and role grid logic window.showEmojiPicker = (anchor, callback) => UniversalEmojiPicker.show(anchor, callback, { width: '350px', height: '400px' }); - // Update role editor emoji triggers - function setupRoleEmojiTriggers() { - const triggers = [ - { btn: 'role-emoji-select-btn', target: 'edit-role-icon', preview: 'selected-role-emoji-preview' }, - { btn: 'add-autorole-emoji-btn', target: 'add-autorole-icon', preview: 'add-autorole-emoji-preview' }, - { btn: 'edit-autorole-emoji-btn', target: 'edit-autorole-icon', preview: 'edit-autorole-emoji-preview' } - ]; - - triggers.forEach(t => { - const btn = document.getElementById(t.btn); - if (btn) { - btn.onclick = (e) => { - e.preventDefault(); - UniversalEmojiPicker.show(btn, (emoji) => { - const input = document.getElementById(t.target); - const preview = document.getElementById(t.preview); - if (input) input.value = emoji; - if (preview) preview.textContent = emoji; - }, { width: '350px', height: '400px' }); - }; + window.renderEmojiToElement = (code, el) => { + if (!el) return; + if (!code) { + el.innerHTML = ""; + return; + } + if (typeof code === "string" && code.startsWith(':') && code.endsWith(':')) { + const ce = window.CUSTOM_EMOTES_CACHE.find(e => e.code === code); + if (ce) { + el.innerHTML = ``; + return; } - }); + } + el.textContent = code; + }; + + // Unified Emoji Picker & Modal Logic + document.addEventListener("click", (e) => { + // Emoji Picker Triggers + const triggers = { + "role-emoji-select-btn": { target: "edit-role-icon", preview: "selected-role-emoji-preview" }, + "add-autorole-emoji-btn": { target: "add-autorole-icon", preview: "add-autorole-emoji-preview" }, + "edit-autorole-emoji-btn": { target: "edit-autorole-icon", preview: "edit-autorole-emoji-preview" } + }; + + const btn = e.target.closest("button[id]"); + if (btn && triggers[btn.id]) { + e.preventDefault(); + const config = triggers[btn.id]; + UniversalEmojiPicker.show(btn, (emoji) => { + const input = document.getElementById(config.target); + const preview = document.getElementById(config.preview); + if (input) input.value = emoji; + window.renderEmojiToElement(emoji, preview); + }, { width: "350px", height: "400px" }); + return; + } // Chat Emoji Picker - const chatEmojiBtn = document.getElementById('chat-emoji-btn'); - const chatInput = document.getElementById('chat-input'); - if (chatEmojiBtn && chatInput) { - chatEmojiBtn.onclick = (e) => { - e.preventDefault(); - UniversalEmojiPicker.show(chatEmojiBtn, (emoji) => { + const chatEmojiBtn = e.target.closest("#chat-emoji-btn"); + if (chatEmojiBtn) { + e.preventDefault(); + UniversalEmojiPicker.show(chatEmojiBtn, (emoji) => { + const chatInput = document.getElementById("chat-input"); + if (chatInput) { chatInput.value += emoji; chatInput.focus(); - }, { keepOpen: true, width: '350px', height: '400px' }); - }; + } + }, { keepOpen: true, width: "350px", height: "400px" }); + return; } - } - // Call setup - setupRoleEmojiTriggers(); + // Autorole Edit modal filling + const editAutoroleBtn = e.target.closest(".edit-autorole-btn"); + if (editAutoroleBtn) { + const id = editAutoroleBtn.dataset.id; + const icon = editAutoroleBtn.dataset.icon; + const title = editAutoroleBtn.dataset.title; + const roleId = editAutoroleBtn.dataset.roleId; + + const idInput = document.getElementById("edit-autorole-id"); + const iconInput = document.getElementById("edit-autorole-icon"); + const titleInput = document.getElementById("edit-autorole-title"); + const roleIdInput = document.getElementById("edit-autorole-role-id"); + const preview = document.getElementById("edit-autorole-emoji-preview"); + + if (idInput) idInput.value = id; + if (iconInput) iconInput.value = icon; + if (titleInput) titleInput.value = title; + if (roleIdInput) roleIdInput.value = roleId; + + if (preview) window.renderEmojiToElement(icon, preview); + return; + } + }); + + window.loadCustomEmotes(); // Scroll to bottom scrollToBottom(true); @@ -2158,6 +2423,15 @@ document.addEventListener('DOMContentLoaded', () => { return div.innerHTML; } + function parseCustomEmotes(text) { + let parsed = escapeHTML(text); + (window.CUSTOM_EMOTES_CACHE || []).forEach(emote => { + const imgHtml = `${emote.name}`; + parsed = parsed.split(emote.code).join(imgHtml); + }); + return parsed; + } + function appendMessage(msg) { if (!msg || !msg.id) return; if (document.querySelector(`.message-item[data-id="${msg.id}"]`)) return; @@ -2238,53 +2512,24 @@ document.addEventListener('DOMContentLoaded', () => { ` : ''; const mentionRegex = new RegExp(`@${window.currentUsername}\\b`, 'g'); - if (msg.content.match(mentionRegex)) { - div.classList.add('mentioned'); - } - if (msg.is_pinned) div.classList.add('pinned'); - - const ytRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:watch\?v=|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/; - const dmRegex = /(?:https?:\/\/)?(?:www\.)?(?:dailymotion\.com\/video\/|dai\.ly\/)([a-zA-Z0-9]+)/; - const vimeoRegex = /(?:https?:\/\/)?(?:www\.)?vimeo\.com\/(\d+)/; - - const ytMatch = msg.content.match(ytRegex); - const dmMatch = msg.content.match(dmRegex); - const vimeoMatch = msg.content.match(vimeoRegex); - - let videoHtml = ''; - if (ytMatch && ytMatch[1]) { - videoHtml = `
`; - } else if (dmMatch && dmMatch[1]) { - videoHtml = `
`; - } else if (vimeoMatch && vimeoMatch[1]) { - videoHtml = `
`; - } - - const authorStyle = msg.role_color ? `color: ${msg.role_color};` : ''; - - const isRoleIconUrl = msg.role_icon && (msg.role_icon.startsWith('http') || msg.role_icon.startsWith('/')); - const roleIcon = msg.role_icon ? (isRoleIconUrl ? `` : `${msg.role_icon}`) : ''; + const mentionHtml = `@${window.currentUsername}`; + const contentWithMentions = parseCustomEmotes(msg.content).replace(mentionRegex, mentionHtml); div.innerHTML = `
- ${escapeHTML(msg.username)} - ${roleIcon} - ${msg.time} + ${escapeHTML(msg.username)} + ${msg.timestamp || 'Just now'} ${pinnedBadge}
-
- ${escapeHTML(msg.content).replace(/\n/g, '
').replace(mentionRegex, `@${window.currentUsername}`)} - ${attachmentHtml} - ${videoHtml} - ${embedHtml} -
-
- + -
+
${contentWithMentions.replace(/\n/g, '
')}
+ ${attachmentHtml} + ${embedHtml} +
${actionsHtml} +
`; messagesList.appendChild(div); scrollToBottom(isMe); @@ -2352,45 +2597,5 @@ document.addEventListener('DOMContentLoaded', () => { } }); - // Edit Autorole Modal Population - document.addEventListener('click', (e) => { - const btn = e.target.closest('.edit-autorole-btn'); - if (!btn) return; - const id = btn.dataset.id; - const icon = btn.dataset.icon; - const title = btn.dataset.title; - const roleId = btn.dataset.roleId; - - document.getElementById('edit-autorole-id').value = id; - document.getElementById('edit-autorole-icon').value = icon; - document.getElementById('edit-autorole-title').value = title; - document.getElementById('edit-autorole-role-id').value = roleId; - - // Update preview - const preview = document.getElementById('edit-autorole-emoji-preview'); - if (preview) preview.textContent = icon; - }); - - // Universal Emoji Picker Trigger - document.addEventListener('click', (e) => { - const btn = e.target.closest('.open-emoji-picker'); - if (!btn) return; - - const targetId = btn.dataset.target; - const targetInput = document.querySelector(targetId); - - if (typeof showEmojiPicker === 'function') { - showEmojiPicker(btn, (emoji) => { - if (targetInput) { - targetInput.value = emoji; - // Special case for role settings preview - if (targetId === '#edit-role-icon') { - const preview = document.getElementById('selected-role-emoji-preview'); - if (preview) preview.textContent = emoji; - } - } - }); - } - }); }); diff --git a/assets/pasted-20260216-132213-80b79cbe.png b/assets/pasted-20260216-132213-80b79cbe.png new file mode 100644 index 0000000000000000000000000000000000000000..b8b920ecbb5025754417b8806ceac794de46be1a GIT binary patch literal 68168 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 MsA;KIC|d;m7fag-*8l(j literal 0 HcmV?d00001 diff --git a/assets/pasted-20260216-162915-c3590120.png b/assets/pasted-20260216-162915-c3590120.png new file mode 100644 index 0000000000000000000000000000000000000000..1c8e4f1938b8139752274096fe9489d1faa1e55a GIT binary patch literal 23279 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'; } elseif ($isFa) { return ''; + } elseif ($isCustomEmote) { + // Fetch emote path + static $ce_icons_cache; + if ($ce_icons_cache === null) { + try { $ce_icons_cache = db()->query("SELECT code, path FROM custom_emotes")->fetchAll(PDO::FETCH_KEY_PAIR); } catch (Exception $e) { $ce_icons_cache = []; } + } + if (isset($ce_icons_cache[$icon])) { + return ''; + } + return '' . htmlspecialchars($icon) . ''; } else { return '' . htmlspecialchars($icon) . ''; } } + +// Helper to parse emotes in content +function parse_emotes($content) { + static $custom_emotes_cache; + if ($custom_emotes_cache === null) { + try { + $custom_emotes_cache = db()->query("SELECT name, path, code FROM custom_emotes")->fetchAll(); + } catch (Exception $e) { + $custom_emotes_cache = []; + } + } + + $result = htmlspecialchars($content); + foreach ($custom_emotes_cache as $ce) { + $emote_html = '' . htmlspecialchars($ce['name']) . ''; + $result = str_replace($ce['code'], $emote_html, $result); + } + return $result; +} requireLogin(); $user = getCurrentUser(); @@ -672,7 +702,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; data-role-id="" data-id="" style=""> - +
@@ -801,6 +831,17 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; @' . htmlspecialchars($user['username']) . '', $msg_content); + + // Custom Emotes parsing + static $custom_emotes_cache; + if ($custom_emotes_cache === null) { + $custom_emotes_cache = db()->query("SELECT name, path, code FROM custom_emotes")->fetchAll(); + } + foreach ($custom_emotes_cache as $ce) { + $emote_html = '' . htmlspecialchars($ce['name']) . ''; + $msg_content = str_replace($ce['code'], $emote_html, $msg_content); + } + echo nl2br($msg_content); ?> @@ -851,7 +892,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; $reacted = in_array($current_user_id, explode(',', $r['users'])); ?> - + + @@ -1024,6 +1065,9 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; + @@ -1138,6 +1182,27 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
+
+
+
+ +
+
+
+ +
+ + +
+
+
+ +
+
+
+
diff --git a/requests.log b/requests.log index 00bc576..1cd2039 100644 --- a/requests.log +++ b/requests.log @@ -209,3 +209,28 @@ 2026-02-16 13:06:41 - GET /index.php?server_id=1&channel_id=1 - POST: [] 2026-02-16 13:06:43 - GET /index.php?server_id=1&channel_id=1 - POST: [] 2026-02-16 13:06:45 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 13:11:31 - GET /?fl_project=38443 - POST: [] +2026-02-16 13:13:37 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 13:18:51 - GET /?fl_project=38443 - POST: [] +2026-02-16 13:19:22 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 13:25:42 - GET /?fl_project=38443 - POST: [] +2026-02-16 13:38:52 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 13:44:04 - GET /?fl_project=38443 - POST: [] +2026-02-16 14:10:45 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 14:10:52 - GET /index.php - POST: [] +2026-02-16 14:10:57 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 14:11:06 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 14:13:29 - GET /?fl_project=38443 - POST: [] +2026-02-16 16:20:04 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:20:11 - GET /index.php - POST: [] +2026-02-16 16:20:31 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:20:47 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:23:59 - GET / - POST: [] +2026-02-16 16:24:07 - GET /?fl_project=38443 - POST: [] +2026-02-16 16:24:48 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:24:51 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:25:36 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:32:41 - GET / - POST: [] +2026-02-16 16:32:49 - GET /?fl_project=38443 - POST: [] +2026-02-16 16:32:51 - GET /index.php?server_id=1&channel_id=17 - POST: [] +2026-02-16 16:33:28 - GET /index.php?server_id=1&channel_id=17 - POST: []