From b531188143ac8f627333154d20674bb8ba649fa7 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:03:07 -0500 Subject: [PATCH] up --- api/react_message.php | 37 +++++++++++++++++++++++++++++++++++++ conversations.php | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/api/react_message.php b/api/react_message.php index 469a7e5..377980f 100644 --- a/api/react_message.php +++ b/api/react_message.php @@ -10,12 +10,49 @@ $input = json_decode(file_get_contents('php://input'), true) ?: $_POST; $message_id = $input['message_id'] ?? null; $emoji = $input['emoji'] ?? null; +// Helper: normalize emoji aliases (e.g., 'corazon' -> '❤️') and decode HTML entities +function normalize_emoji($s) { + if (!$s) return $s; + // decode numeric HTML entities like ❤ etc. + $s = html_entity_decode($s, ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $orig = $s; + $s_trim = trim(mb_strtolower($s, 'UTF-8')); + + $map = [ + 'corazon' => '❤️', 'heart' => '❤️', '<3' => '❤️', + 'like' => '👍', 'thumbsup' => '👍', 'thumbs_up' => '👍', '👍' => '👍', + 'laugh' => '😂', 'risa' => '😂', 'joy' => '😂', + 'wow' => '😮', 'surprised' => '😮', + 'sad' => '😢', 'triste' => '😢', + 'clap' => '👏', 'applause' => '👏', + 'party' => '🎉', 'celebrate' => '🎉', + 'fire' => '🔥', + 'pray' => '🙏', 'thanks' => '🙏' + ]; + + // If the string looks like an alias (letters, dashes, underscores, or short), map it + $key = preg_replace('/[^a-z0-9_\-]/u', '', $s_trim); + if (isset($map[$key])) return $map[$key]; + + // If the string itself contains an emoji (most common case), return the first emoji-like char or the original + // A simple heuristic: keep any non-ASCII or known emoji utf ranges + if (preg_match('/[\x{1F300}-\x{1F6FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]/u', $orig, $m)) { + return $m[0]; + } + + // fallback to original trimmed string + return trim($orig); +} + if (!$message_id || !$emoji) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Parámetros faltantes: message_id, emoji']); exit; } +// Normalize emoji early +$emoji = normalize_emoji($emoji); + try { $db = Database::getInstance(); diff --git a/conversations.php b/conversations.php index 73d9233..861e065 100644 --- a/conversations.php +++ b/conversations.php @@ -1240,7 +1240,22 @@ const t = ev.target; if (t && t.dataset && t.dataset.emoji) { ev.stopPropagation(); - const emoji = t.dataset.emoji; + // Normalize alias -> emoji on client side too + const alias = t.dataset.emoji; + const clientEmojiMap = { + 'corazon': '❤️','heart':'❤️','<3':'❤️', + 'like':'👍','thumbs_up':'👍','thumbsup':'👍', + 'laugh':'😂','risa':'😂','joy':'😂', + 'wow':'😮','surprised':'😮', + 'sad':'😢','triste':'😢', + 'clap':'👏','applause':'👏', + 'party':'🎉','celebrate':'🎉', + 'fire':'🔥','pray':'🙏' + }; + let emoji = alias; + const key = (alias || '').toLowerCase().replace(/[^a-z0-9_\-]/g,''); + if (clientEmojiMap[key]) emoji = clientEmojiMap[key]; + const mid = this._pendingReactionMessage; if (!mid) return; try { @@ -2813,14 +2828,34 @@ if (!container) return; const el = container.querySelector(`[data-message-id="${messageId}"]`); if (!el) return; + + // normalize emoji aliases (fallback mapping) + const clientEmojiMap = { + 'corazon': '❤️','heart':'❤️','<3':'❤️', + 'like':'👍','thumbs_up':'👍','thumbsup':'👍', + 'laugh':'😂','risa':'😂','joy':'😂', + 'wow':'😮','surprised':'😮','sad':'😢','triste':'😢', + 'clap':'👏','party':'🎉','fire':'🔥','pray':'🙏' + }; + + let display = emoji || ''; + if (display && /^[a-z0-9_\-]+$/i.test(display)) { + const key = display.toLowerCase(); + if (clientEmojiMap[key]) display = clientEmojiMap[key]; + } else { + // if it's a longer string, attempt to extract the first emoji char + const m = (display || '').match(/[\x{1F300}-\x{1F6FF}\x{1F900}-\x{1F9FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]/u); + if (m && m[0]) display = m[0]; + } + let badge = el.querySelector('.reaction-badge'); - if (emoji) { + if (display) { if (badge) { - badge.textContent = emoji; + badge.textContent = display; } else { const div = document.createElement('div'); div.className = 'reaction-badge'; - div.textContent = emoji; + div.textContent = display; const bubble = el.querySelector('.message-bubble'); if (bubble) bubble.insertBefore(div, bubble.querySelector('.message-actions')); }