From 98888d0370730c32c6852423cb31e39d21fbbed1 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 15 Feb 2026 19:21:41 +0000 Subject: [PATCH] emoji sur les roles --- assets/js/main.js | 214 +++++++++++++++++++++++++++++++++++++++++----- index.php | 33 +++++-- 2 files changed, 216 insertions(+), 31 deletions(-) diff --git a/assets/js/main.js b/assets/js/main.js index a8dfe2e..741f6cc 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -27,8 +27,103 @@ document.addEventListener('DOMContentLoaded', () => { } } - // Emoji list for reactions - const EMOJIS = ['๐Ÿ‘', 'โค๏ธ', '๐Ÿ˜‚', '๐Ÿ˜ฎ', '๐Ÿ˜ข', '๐Ÿ”ฅ', 'โœ…', '๐Ÿš€', 'โ“', '๐Ÿ’ก', '๐Ÿ“Œ', '๐Ÿ’ฏ']; + // Emoji list categorized + const EMOJI_CATEGORIES = { + 'Smileys': ['๐Ÿ˜€', '๐Ÿ˜ƒ', '๐Ÿ˜„', '๐Ÿ˜', '๐Ÿ˜†', '๐Ÿ˜…', '๐Ÿคฃ', '๐Ÿ˜‚', '๐Ÿ™‚', '๐Ÿ™ƒ', '๐Ÿ˜‰', '๐Ÿ˜Š', '๐Ÿ˜‡', '๐Ÿฅฐ', '๐Ÿ˜', '๐Ÿคฉ', '๐Ÿ˜˜', '๐Ÿ˜—', '๐Ÿ˜š', '๐Ÿ˜™', '๐Ÿ˜‹', '๐Ÿ˜›', '๐Ÿ˜œ', '๐Ÿคช', '๐Ÿ˜', '๐Ÿค‘', '๐Ÿค—', '๐Ÿคญ', '๐Ÿคซ', '๐Ÿค”', '๐Ÿค', '๐Ÿคจ', '๐Ÿ˜', '๐Ÿ˜‘', '๐Ÿ˜ถ', '๐Ÿ˜', '๐Ÿ˜’', '๐Ÿ™„', '๐Ÿ˜ฌ', '๐Ÿคฅ', '๐Ÿ˜Œ', '๐Ÿ˜”', '๐Ÿ˜ช', '๐Ÿคค', '๐Ÿ˜ด', '๐Ÿ˜ท', '๐Ÿค’', '๐Ÿค•', '๐Ÿคข', '๐Ÿคฎ', '๐Ÿคง', '๐Ÿฅต', '๐Ÿฅถ', '๐Ÿฅด', '๐Ÿ˜ต', '๐Ÿคฏ', '๐Ÿค ', '๐Ÿฅณ', '๐Ÿ˜Ž', '๐Ÿค“', '๐Ÿง', '๐Ÿ˜•', '๐Ÿ˜Ÿ', '๐Ÿ™', 'โ˜น๏ธ', '๐Ÿ˜ฎ', '๐Ÿ˜ฏ', '๐Ÿ˜ฒ', '๐Ÿ˜ณ', '๐Ÿฅบ', '๐Ÿ˜ฆ', '๐Ÿ˜ง', '๐Ÿ˜จ', '๐Ÿ˜ฐ', '๐Ÿ˜ฅ', '๐Ÿ˜ข', '๐Ÿ˜ญ', '๐Ÿ˜ฑ', '๐Ÿ˜–', '๐Ÿ˜ฃ', '๐Ÿ˜ž', '๐Ÿ˜“', '๐Ÿ˜ฉ', '๐Ÿ˜ซ', '๐Ÿฅฑ', '๐Ÿ˜ค', '๐Ÿ˜ก', '๐Ÿ˜ ', '๐Ÿคฌ', '๐Ÿ˜ˆ', '๐Ÿ‘ฟ', '๐Ÿ‘น', '๐Ÿ‘บ', '๐Ÿ’€', 'โ˜ ๏ธ', '๐Ÿ’ฉ', '๐Ÿคก', '๐Ÿ‘น', '๐Ÿ‘บ', '๐Ÿ‘ป', '๐Ÿ‘ฝ', '๐Ÿ‘พ', '๐Ÿค–', '๐Ÿ˜บ', '๐Ÿ˜ธ', '๐Ÿ˜ป', '๐Ÿ˜ผ', '๐Ÿ˜ฝ', '๐Ÿ™€', '๐Ÿ˜ฟ', '๐Ÿ˜พ'], + 'People': ['๐Ÿ‘‹', '๐Ÿคš', '๐Ÿ–๏ธ', 'โœ‹', '๐Ÿ––', '๐Ÿ‘Œ', '๐Ÿค', 'โœŒ๏ธ', '๐Ÿคž', '๐ŸคŸ', '๐Ÿค˜', '๐Ÿค™', '๐Ÿ‘ˆ', '๐Ÿ‘‰', '๐Ÿ‘†', '๐Ÿ–•', '๐Ÿ‘‡', 'โ˜๏ธ', '๐Ÿ‘', '๐Ÿ‘Ž', 'โœŠ', '๐Ÿ‘Š', '๐Ÿค›', '๐Ÿคœ', '๐Ÿ‘', '๐Ÿ™Œ', '๐Ÿ‘', '๐Ÿคฒ', '๐Ÿค', '๐Ÿ™', 'โœ๏ธ', '๐Ÿ’…', '๐Ÿคณ', '๐Ÿ’ช', '๐Ÿฆพ', '๐Ÿฆต', '๐Ÿฆฟ', '๐Ÿฆถ', '๐Ÿ‘‚', '๐Ÿฆป', '๐Ÿ‘ƒ', '๐Ÿง ', '๐Ÿฆท', '๐Ÿฆด', '๐Ÿ‘€', '๐Ÿ‘๏ธ', '๐Ÿ‘…', '๐Ÿ‘„', '๐Ÿ‘ถ', '๐Ÿง’', '๐Ÿ‘ฆ', '๐Ÿ‘ง', '๐Ÿง‘', '๐Ÿ‘ฑ', '๐Ÿ‘จ', '๐Ÿง”', '๐Ÿ‘ฉ', '๐Ÿง“', '๐Ÿ‘ด', '๐Ÿ‘ต', '๐Ÿ‘ฎ', '๐Ÿ•ต๏ธ', '๐Ÿ’‚', '๐Ÿ‘ท', '๐Ÿคด', '๐Ÿ‘ธ', '๐Ÿ‘ณ', '๐Ÿ‘ฒ', '๐Ÿง•', '๐Ÿคต', '๐Ÿ‘ฐ', '๐Ÿคฐ', '๐Ÿคฑ', '๐Ÿ‘ผ', '๐ŸŽ…', '๐Ÿคถ', '๐Ÿฆธ', '๐Ÿฆน', '๐Ÿง™', '๐Ÿงš', '๐Ÿง›', '๐Ÿงœ', '๐Ÿง', '๐Ÿงž', '๐ŸงŸ', '๐Ÿ’†', '๐Ÿ’‡', '๐Ÿšถ', '๐Ÿƒ', '๐Ÿ’ƒ', '๐Ÿ•บ', '๐Ÿ•ด๏ธ', '๐Ÿ‘ฏ', '๐Ÿง–', '๐Ÿง—'], + 'Animals': ['๐Ÿถ', '๐Ÿฑ', '๐Ÿญ', '๐Ÿน', '๐Ÿฐ', '๐ŸฆŠ', '๐Ÿป', '๐Ÿผ', '๐Ÿจ', '๐Ÿฏ', '๐Ÿฆ', '๐Ÿฎ', '๐Ÿท', '๐Ÿฝ', '๐Ÿธ', '๐Ÿต', '๐Ÿ™ˆ', '๐Ÿ™‰', '๐Ÿ™Š', '๐Ÿ’', '๐Ÿ”', '๐Ÿง', '๐Ÿฆ', '๐Ÿค', '๐Ÿฃ', '๐Ÿฅ', '๐Ÿฆ†', '๐Ÿฆ…', '๐Ÿฆ‰', '๐Ÿฆ‡', '๐Ÿบ', '๐Ÿ—', '๐Ÿด', '๐Ÿฆ„', '๐Ÿ', '๐Ÿ›', '๐Ÿฆ‹', '๐ŸŒ', '๐Ÿž', '๐Ÿœ', '๐ŸฆŸ', '๐Ÿฆ—', '๐Ÿ•ท๏ธ', '๐Ÿ•ธ๏ธ', '่ ', '๐Ÿข', '๐Ÿ', '๐ŸฆŽ', '๐Ÿฆ–', '๐Ÿฆ•', '๐Ÿ™', '๐Ÿฆ‘', '๐Ÿฆ', '๐Ÿฆž', '๐Ÿฆ€', '๐Ÿก', '๐Ÿ ', '๐ŸŸ', '๐Ÿฌ', '๐Ÿณ', '๐Ÿ‹', '๐Ÿฆˆ', '๐ŸŠ', '๐Ÿ…', '๐Ÿ†', '๐Ÿฆ“', '๐Ÿฆ', '๐Ÿฆง', '๐Ÿ˜', '๐Ÿฆ›', '๐Ÿฆ', '๐Ÿช', '๐Ÿซ', '๐Ÿฆ’', '๐Ÿฆ˜', '๐Ÿƒ', '๐Ÿ‚', '๐Ÿ„', '๐ŸŽ', '๐Ÿ–', '๐Ÿ', '๐Ÿ‘', '๐Ÿ', '๐ŸฆŒ', '๐Ÿ•', '๐Ÿฉ', '๐Ÿฆฎ', '๐Ÿˆ', '๐Ÿ“', '๐Ÿฆƒ', '๐Ÿฆš', '๐Ÿฆœ', '๐Ÿฆข', '๐Ÿฆฉ', '๐Ÿ•Š๏ธ', '๐Ÿ‡', '๐Ÿฆ', '๐Ÿฆจ', '๐Ÿฆก', '๐Ÿฆฆ', '๐Ÿฆฅ', '๐Ÿ', '๐Ÿ€', '๐Ÿฟ๏ธ', '๐Ÿฆ”'], + 'Nature': ['๐ŸŒต', '๐ŸŽ„', '๐ŸŒฒ', '๐ŸŒณ', '๐ŸŒด', '๐ŸŒฑ', '๐ŸŒฟ', 'โ˜˜๏ธ', '๐Ÿ€', '๐ŸŽ', '๐ŸŽ‹', '๐Ÿƒ', '๐Ÿ‚', '๐Ÿ', '๐Ÿ„', '๐Ÿš', '๐ŸŒพ', '๐Ÿ’', '๐ŸŒท', '๐ŸŒน', '๐Ÿฅ€', '๐ŸŒบ', '๐ŸŒธ', '๐ŸŒผ', '๐ŸŒป', '๐ŸŒž', '๐ŸŒ', '๐ŸŒ›', '๐ŸŒœ', '๐ŸŒš', '๐ŸŒ•', '๐ŸŒ–', '๐ŸŒ—', '๐ŸŒ˜', '๐ŸŒ‘', '๐ŸŒ’', '๐ŸŒ“', '๐ŸŒ”', '๐ŸŒ™', '๐ŸŒŽ', '๐ŸŒ', '๐ŸŒ', '๐Ÿช', '๐Ÿ’ซ', 'โญ๏ธ', '๐ŸŒŸ', 'โœจ', 'โšก๏ธ', 'โ˜„๏ธ', '๐Ÿ’ฅ', '๐Ÿ”ฅ', '๐ŸŒช๏ธ', '๐ŸŒˆ', 'โ˜€๏ธ', '๐ŸŒค๏ธ', 'โ›…๏ธ', '๐ŸŒฅ๏ธ', 'โ˜๏ธ', '๐ŸŒฆ๏ธ', '๐ŸŒง๏ธ', '๐ŸŒจ๏ธ', '๐ŸŒฉ๏ธ', 'โ„๏ธ', 'โ˜ƒ๏ธ', 'โ›„๏ธ', '๐ŸŒฌ๏ธ', '๐Ÿ’จ', '๐Ÿ’ง', '๐Ÿ’ฆ', 'โ˜”๏ธ', 'โ˜‚๏ธ', '๐ŸŒŠ', '๐ŸŒซ๏ธ'], + 'Food': ['๐Ÿ', '๐ŸŽ', '๐Ÿ', '๐ŸŠ', '๐Ÿ‹', ' BANANA', '๐Ÿ‰', '๐Ÿ‡', '๐Ÿ“', '๐Ÿˆ', '๐Ÿ’', '๐Ÿ‘', '๐Ÿฅญ', '๐Ÿ', '๐Ÿฅฅ', '๐Ÿฅ', '๐Ÿ…', '๐Ÿ†', '๐Ÿฅ‘', '๐Ÿฅฆ', '๐Ÿฅฌ', '๐Ÿฅ’', '๐ŸŒฝ', '๐Ÿฅ•', '๐Ÿง„', '๐Ÿฅ”', '๐Ÿ ', '๐Ÿฅ', '๐Ÿฅฏ', '๐Ÿž', '๐Ÿฅ–', '๐Ÿฅจ', '๐Ÿง€', '๐Ÿฅš', '๐Ÿณ', '๐Ÿงˆ', '๐Ÿฅž', ' waffle', '๐Ÿฅ“', '๐Ÿฅฉ', '๐Ÿ—', '๐Ÿ–', '๐Ÿฆด', '๐ŸŒญ', '๐Ÿ”', '๐ŸŸ', '๐Ÿ•', '๐Ÿฅช', '๐Ÿฅ™', '๐Ÿง†', '๐ŸŒฎ', '๐ŸŒฏ', '๐Ÿฅ—', '๐Ÿฅ˜', '๐Ÿ', '๐Ÿœ', '๐Ÿฒ', '๐Ÿ›', ' sushi', ' Bento', ' Dumpling', ' Oyster', '๐Ÿค', ' Rice Ball', ' Rice', ' Rice Cracker', '๐Ÿฅ', '๐Ÿฅ ', '๐Ÿฅฎ', '๐Ÿข', '๐Ÿก', '๐Ÿง', '๐Ÿจ', '๐Ÿฆ', '๐Ÿฅง', '๐Ÿง', '๐Ÿฐ', '๐ŸŽ‚', '๐Ÿฎ', '๐Ÿญ', '๐Ÿฌ', '๐Ÿซ', ' popcorn', '๐Ÿฉ', '๐Ÿช', '๐ŸŒฐ', ' peanuts', '๐Ÿฏ', '๐Ÿฅ›', 'โ˜•๏ธ', '๐Ÿต', '๐Ÿฅค', '๐Ÿถ', '๐Ÿบ', '๐Ÿป', '๐Ÿฅ‚', '๐Ÿท', '๐Ÿฅƒ', '๐Ÿธ', '๐Ÿน', '๐Ÿง‰', '๐Ÿพ', '๐ŸงŠ', '๐Ÿฅ„', '๐Ÿด', '๐Ÿฝ๏ธ', '๐Ÿฅฃ', '๐Ÿฅก'], + 'Travel': ['๐Ÿš—', '๐Ÿš•', '๐Ÿš™', '๐ŸšŒ', '๐ŸšŽ', '๐ŸŽ๏ธ', '๐Ÿš“', '๐Ÿš‘', '๐Ÿš’', '๐Ÿš', '๐Ÿšš', '๐Ÿš›', '๐Ÿšœ', '๐Ÿ›ต', '๐Ÿšฒ', '๐Ÿ›ด', '๐Ÿš', '๐Ÿ›ฃ๏ธ', '๐Ÿ›ค๏ธ', 'โ›ฝ๏ธ', '๐Ÿšจ', '๐Ÿšฅ', '๐Ÿšฆ', '๐Ÿšง', 'โš“๏ธ', 'โ›ต๏ธ', '๐Ÿšค', '๐Ÿ›ณ๏ธ', 'โ›ด๏ธ', '๐Ÿšข', 'โœˆ๏ธ', '๐Ÿ›ซ', '๐Ÿ›ฌ', '๐Ÿ’บ', '๐Ÿš', '๐ŸšŸ', '๐Ÿš ', '๐Ÿšก', '๐Ÿš€', '๐Ÿ›ธ', '๐Ÿ›ฐ๏ธ', 'โŒ›๏ธ', 'โณ', 'โŒš๏ธ', 'โฐ', 'โฑ๏ธ', 'โฒ๏ธ', '๐Ÿ•ฐ๏ธ', '๐ŸŒก๏ธ', 'โ˜€๏ธ', '๐Ÿช', '๐ŸŒŸ', 'โ˜๏ธ', 'โ›…๏ธ', 'โ›ˆ๏ธ', '๐ŸŒˆ', 'โ›ฐ๏ธ', '๐Ÿ”๏ธ', '๐Ÿ—ป', '๐ŸŒ‹', '๐Ÿœ๏ธ', '๐Ÿ•๏ธ', 'โ›บ๏ธ', '๐Ÿ ', '๐Ÿก', '๐Ÿข', '๐Ÿฃ', '๐Ÿค', '๐Ÿฅ', '๐Ÿฆ', '๐Ÿจ', '๐Ÿฉ', '๐Ÿช', '๐Ÿซ', '๐Ÿฌ', '๐Ÿญ', '๐Ÿฏ', '๐Ÿฐ', '๐Ÿ’’', '๐Ÿ—ผ', '๐Ÿ—ฝ', 'โ›ช๏ธ', '๐Ÿ•Œ', '๐Ÿ•', 'โ›ฉ๏ธ', '๐Ÿ•‹', 'โ›ฒ๏ธ', '๐ŸŒ', '๐ŸŒƒ', '๐Ÿ™๏ธ', '๐ŸŒ„', '๐ŸŒ…', '๐ŸŒ†', '๐ŸŒ‡', '๐ŸŒ‰', '๐ŸŽ ', '๐ŸŽก', '๐ŸŽข', '๐Ÿš‚', '๐Ÿšƒ', '๐Ÿš„', '๐Ÿš…', '๐Ÿš†', '๐Ÿš‡', '๐Ÿšˆ', '๐Ÿš‰', '๐ŸšŠ', '๐Ÿš', '๐Ÿšž', '๐Ÿš‹'], + 'Activities': ['โšฝ๏ธ', '๐Ÿ€', '๐Ÿˆ', 'โšพ๏ธ', '๐ŸฅŽ', '๐ŸŽพ', '๐Ÿ', '๐Ÿ‰', '๐ŸŽฑ', '๐Ÿ“', '๐Ÿธ', '๐Ÿฅ…', ' hockey', ' field hockey', ' cricket', 'โ›ณ๏ธ', '๐Ÿน', '๐ŸŽฃ', ' boxing', '๐Ÿฅ‹', ' skateboard', '๐Ÿ›ท', 'โ›ธ๏ธ', '๐ŸฅŒ', '๐ŸŽฟ', 'โ›ท๏ธ', '๐Ÿ‚', '๐Ÿ‹๏ธ', ' fencing', '๐Ÿคผ', ' gymnastics', ' basketball player', '๐Ÿคฝ', ' handball', ' juggle', '๐Ÿง˜', '๐Ÿ‡', ' rowing', ' swimming', '๐Ÿšด', '๐Ÿšต', '๐Ÿง—', '๐ŸŽ–๏ธ', '๐Ÿ†', '๐Ÿ…', '๐Ÿฅ‡', '๐Ÿฅˆ', '๐Ÿฅ‰', '๐ŸŽซ', '๐ŸŽŸ๏ธ', '๐ŸŽญ', '๐ŸŽจ', '๐ŸŽฌ', '๐ŸŽค', '๐ŸŽง', '๐ŸŽผ', '๐ŸŽน', '๐Ÿฅ', '๐ŸŽท', '๐ŸŽบ', '๐ŸŽธ', '๐Ÿช•', '๐ŸŽป', '๐ŸŽฒ', 'โ™Ÿ๏ธ', '๐ŸŽฏ', '๐ŸŽณ', '๐ŸŽฎ', '๐ŸŽฐ', '๐Ÿงฉ'], + 'Objects': ['โŒš๏ธ', '๐Ÿ“ฑ', '๐Ÿ“ฒ', '๐Ÿ’ป', 'โŒจ๏ธ', '๐Ÿ–ฑ๏ธ', '๐Ÿ–ฒ๏ธ', '๐Ÿ•น๏ธ', '๐Ÿ—œ๏ธ', '๐Ÿ’ฝ', '๐Ÿ’พ', '๐Ÿ’ฟ', '๐ŸŽž๏ธ', '๐Ÿ“ท', '๐Ÿ“ธ', '๐Ÿ“น', '๐Ÿ“ผ', '๐Ÿ”', '๐Ÿ”Ž', '๐Ÿ•ฏ๏ธ', '๐Ÿ’ก', '๐Ÿ”ฆ', '๐Ÿฎ', '๐Ÿช”', '๐Ÿ“”', '๐Ÿ“•', '๐Ÿ“–', '๐Ÿ“—', '๐Ÿ“˜', '๐Ÿ“™', '๐Ÿ“š', '๐Ÿ““', '๐Ÿ“’', '๐Ÿ“ƒ', '๐Ÿ“œ', '๐Ÿ“„', '๐Ÿ“ฐ', '๐Ÿ—ž๏ธ', '๐Ÿ“‘', '๐Ÿ”–', '๐Ÿท๏ธ', '๐Ÿ’ฐ', '๐Ÿ’ด', '๐Ÿ’ต', '๐Ÿ’ถ', '๐Ÿ’ท', '๐Ÿ’ธ', '๐Ÿ’ณ', '๐Ÿงพ', '๐Ÿ’น', 'โœ‰๏ธ', '๐Ÿ“ง', '๐Ÿ“จ', '๐Ÿ“ฉ', '๐Ÿ“ค', '๐Ÿ“ฅ', '๐Ÿ“ฆ', '๐Ÿ“ซ', '๐Ÿ“ฉ', '๐Ÿ“ฌ', '๐Ÿ“ญ', '๐Ÿ“ฎ', '๐Ÿ—ณ๏ธ', 'โœ๏ธ', 'โœ’๏ธ', '๐Ÿ–‹๏ธ', '๐Ÿ–Š๏ธ', '๐Ÿ–Œ๏ธ', '๐Ÿ–๏ธ', '๐Ÿ“', '๐Ÿ’ผ', '๐Ÿ“', '๐Ÿ“‚', '๐Ÿ—‚๏ธ', '๐Ÿ“…', '๐Ÿ“†', '๐Ÿ—’๏ธ', '๐Ÿ—“๏ธ', '๐Ÿ“‡', '๐Ÿ“ˆ', '๐Ÿ“‰', '๐Ÿ“Š', '๐Ÿ“‹', '๐Ÿ“Œ', '๐Ÿ“', '๐Ÿ“Ž', '๐Ÿ–‡๏ธ', '๐Ÿ“', '๐Ÿ“', 'โœ‚๏ธ', '๐Ÿ—ƒ๏ธ', '๐Ÿ—„๏ธ', '๐Ÿ—‘๏ธ', '๐Ÿ”’', '๐Ÿ”“', '๐Ÿ”', '๐Ÿ”', '๐Ÿ”‘', '๐Ÿ—๏ธ', '๐Ÿ”จ', '๐Ÿช“', 'โ›๏ธ', 'โš’๏ธ', '๐Ÿ› ๏ธ', '๐Ÿ—ก๏ธ', 'โš”๏ธ', '๐Ÿ”ซ', '๐Ÿ›ก๏ธ', '๐Ÿ”ง', '๐Ÿ”ฉ', 'โš™๏ธ', '๐Ÿ—œ๏ธ', 'โš–๏ธ', '๐Ÿฆฏ', '๐Ÿ”—', 'โ›“๏ธ', '๐Ÿงฐ', '๐Ÿงฒ', 'โš—๏ธ', '๐Ÿงช', '๐Ÿงซ', '๐Ÿงฌ', '๐Ÿ”ฌ', '๐Ÿ”ญ', '๐Ÿ“ก', '๐Ÿ’‰', '๐Ÿฉธ', '๐Ÿ’Š', '๐Ÿฉน', '๐Ÿฉบ', '๐Ÿšช', '๐Ÿ›๏ธ', '๐Ÿ›‹๏ธ', '๐Ÿช‘', '๐Ÿšฝ', '๐Ÿšฟ', '๐Ÿ›€', '๐Ÿช’', '๐Ÿงด', '๐Ÿงท', '๐Ÿงน', '๐Ÿงบ', '๐Ÿงป', '๐Ÿงผ', '๐Ÿงฏ', '๐Ÿ›’', '๐Ÿšฌ', 'โšฐ๏ธ', 'โšฑ๏ธ', '๐Ÿ—ฟ'], + 'Symbols': ['๐Ÿ’˜', '๐Ÿ’', '๐Ÿ’–', '๐Ÿ’—', '๐Ÿ’“', '๐Ÿ’ž', '๐Ÿ’•', '๐Ÿ’Ÿ', 'โฃ๏ธ', '๐Ÿ’”', 'โค๏ธ', '๐Ÿงก', '๐Ÿ’›', '๐Ÿ’š', '๐Ÿ’™', '๐Ÿ’œ', '๐Ÿ–ค', '๐Ÿค', '๐ŸคŽ', '๐Ÿ’ฏ', '๐Ÿ’ข', '๐Ÿ’ฅ', '๐Ÿ’ซ', '๐Ÿ’ฆ', '๐Ÿ’จ', '๐Ÿ•ณ๏ธ', '๐Ÿ’ฃ', '๐Ÿ’ฌ', '๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ', '๐Ÿ—จ๏ธ', '๐Ÿ—ฏ๏ธ', '๐Ÿ’ญ', '๐Ÿ’ค', '๐ŸŒ', 'โ™ ๏ธ', 'โ™ฅ๏ธ', 'โ™ฆ๏ธ', 'โ™ฃ๏ธ', '๐Ÿƒ', '๐Ÿ€„๏ธ', '๐ŸŽด', '๐ŸŽญ', '๐Ÿ”‡', '๐Ÿ”ˆ', '๐Ÿ”‰', '๐Ÿ”Š', '๐Ÿ“ข', '๐Ÿ“ฃ', '๐Ÿ“ฏ', '๐Ÿ””', '๐Ÿ”•', '๐ŸŽผ', '๐ŸŽต', '๐ŸŽถ', '๐Ÿ’น', '๐Ÿง', '๐Ÿšฎ', '๐Ÿšฐ', 'โ™ฟ๏ธ', '๐Ÿšน', '๐Ÿšบ', '๐Ÿšป', '๐Ÿšผ', '๐Ÿšพ', '๐Ÿ›‚', '๐Ÿ›ƒ', '๐Ÿ›„', '๐Ÿ›…', 'โš ๏ธ', '๐Ÿšธ', 'โ›”๏ธ', '๐Ÿšซ', '๐Ÿšณ', '๐Ÿšญ', '๐Ÿšฏ', '๐Ÿšฑ', '๐Ÿšท', '๐Ÿ“ต', '๐Ÿ”ž', 'โ˜ข๏ธ', 'โ˜ฃ๏ธ', 'โฌ†๏ธ', 'โ†—๏ธ', 'โžก๏ธ', 'โ†˜๏ธ', 'โฌ‡๏ธ', 'โ†™๏ธ', 'โฌ…๏ธ', 'โ†–๏ธ', 'โ†•๏ธ', 'โ†”๏ธ', 'โ†ฉ๏ธ', 'โ†ช๏ธ', 'โคด๏ธ', 'โคต๏ธ', '๐Ÿ”ƒ', '๐Ÿ”„', '๐Ÿ”™', '๐Ÿ”š', '๐Ÿ”›', '๐Ÿ”œ', '๐Ÿ”', '๐Ÿ›', 'โš›๏ธ', '๐Ÿ•‰๏ธ', 'โœก๏ธ', 'โ˜ธ๏ธ', 'โ˜ฏ๏ธ', 'โœ๏ธ', 'โ˜ฆ๏ธ', 'โ˜ช๏ธ', 'โ˜ฎ๏ธ', '๐Ÿ•Ž', '๐Ÿ”ฏ', 'โ™ˆ๏ธ', 'โ™‰๏ธ', 'โ™Š๏ธ', 'โ™‹๏ธ', 'โ™Œ๏ธ', 'โ™๏ธ', 'โ™Ž๏ธ', 'โ™๏ธ', 'โ™๏ธ', 'โ™‘๏ธ', 'โ™’๏ธ', 'โ™“๏ธ', 'โ›Ž', '๐Ÿ”€', '๐Ÿ”', '๐Ÿ”‚', 'โ–ถ๏ธ', 'โฉ', 'โญ๏ธ', 'โฏ๏ธ', 'โ—€๏ธ', 'โช', 'โฎ๏ธ', '๐Ÿ”ผ', 'โซ', '๐Ÿ”ฝ', 'โฌ', 'โธ๏ธ', 'โน๏ธ', 'โบ๏ธ', 'โ๏ธ', '๐ŸŽฆ', '๐Ÿ”…', '๐Ÿ”†', '๐Ÿ“ถ', '๐Ÿ“ณ', '๐Ÿ“ด', 'โž•', 'โž–', 'โž—', 'โœ–๏ธ', 'โ™พ๏ธ', 'โ€ผ๏ธ', 'โ‰๏ธ', 'โ“', 'โ”', 'โ•', 'โ—๏ธ', 'ใ€ฐ๏ธ', '๐Ÿ’ฑ', '๐Ÿ’ฒ', 'โš•๏ธ', 'โ™ป๏ธ', 'โšœ๏ธ', '๐Ÿ”ฑ', '๐Ÿ“›', '๐Ÿ”ฐ', 'โญ•๏ธ', 'โœ…', 'โ˜‘๏ธ', 'โœ”๏ธ', 'โœ–๏ธ', 'โŒ', 'โŽ', 'โžฐ', 'โžฟ', 'ใ€ฝ๏ธ', 'โœณ๏ธ', 'โœด๏ธ', 'โ‡๏ธ', 'โ€ผ๏ธ', '๐Ÿˆ', '๐Ÿˆ‚๏ธ', '๐Ÿˆท๏ธ', '๐Ÿˆถ', '๐Ÿˆฏ๏ธ', '๐Ÿ‰', '๐Ÿˆน', '๐Ÿˆš๏ธ', '๐Ÿˆฒ', '๐Ÿ‰‘', '๐Ÿˆธ', '๐Ÿˆด', '๐Ÿˆณ', 'ใŠ—๏ธ', 'ใŠ™๏ธ', '๐Ÿˆบ', '๐Ÿˆต', '๐Ÿ”ด', '๐ŸŸ ', '๐ŸŸก', '๐ŸŸข', '๐Ÿ”ต', '๐ŸŸฃ', '๐ŸŸค', 'โšซ๏ธ', 'โšช๏ธ', '๐ŸŸฅ', '๐ŸŸง', '๐ŸŸจ', '๐ŸŸฉ', '๐ŸŸฆ', '๐ŸŸช', '๐ŸŸซ', 'โฌ›๏ธ', 'โฌœ๏ธ'], + 'Flags': ['๐Ÿ', '๐Ÿšฉ', '๐ŸŽŒ', '๐Ÿด', '๐Ÿณ๏ธ', '๐Ÿณ๏ธโ€๐ŸŒˆ', '๐Ÿณ๏ธโ€โšง๏ธ', '๐Ÿดโ€โ˜ ๏ธ', '๐Ÿ‡ฆ๐Ÿ‡ซ', '๐Ÿ‡ฆ๐Ÿ‡ฝ', '๐Ÿ‡ฆ๐Ÿ‡ฑ', '๐Ÿ‡ฉ๐Ÿ‡ฟ', '๐Ÿ‡ฆ๐Ÿ‡ฒ', '๐Ÿ‡ฆ๐Ÿ‡บ', '๐Ÿ‡ฆ๐Ÿ‡น', '๐Ÿ‡ฆ๐Ÿ‡ฟ', '๐Ÿ‡ง๐Ÿ‡ช', '๐Ÿ‡ง๐Ÿ‡ท', '๐Ÿ‡จ๐Ÿ‡ฆ', '๐Ÿ‡จ๐Ÿ‡ฑ', '๐Ÿ‡จ๐Ÿ‡ณ', '๐Ÿ‡จ๐Ÿ‡ด', '๐Ÿ‡จ๐Ÿ‡ฟ', '๐Ÿ‡ฉ๐Ÿ‡ฐ', '๐Ÿ‡ช๐Ÿ‡ฌ', '๐Ÿ‡ซ๐Ÿ‡ฎ', '๐Ÿ‡ซ๐Ÿ‡ท', '๐Ÿ‡ฉ๐Ÿ‡ช', '๐Ÿ‡ฌ๐Ÿ‡ท', '๐Ÿ‡ญ๐Ÿ‡ฐ', '๐Ÿ‡ฎ๐Ÿ‡ณ', '๐Ÿ‡ฎ๐Ÿ‡ฉ', '๐Ÿ‡ฎ๐Ÿ‡ช', '๐Ÿ‡ฎ๐Ÿ‡ฑ', '๐Ÿ‡ฎ๐Ÿ‡น', '๐Ÿ‡ฏ๐Ÿ‡ต', '๐Ÿ‡ฐ๐Ÿ‡ท', '๐Ÿ‡ฒ๐Ÿ‡ฝ', '๐Ÿ‡ณ๐Ÿ‡ฑ', '๐Ÿ‡ณ๐Ÿ‡ฟ', '๐Ÿ‡ณ๐Ÿ‡ด', '๐Ÿ‡ต๐Ÿ‡ฐ', '๐Ÿ‡ต๐Ÿ‡ญ', '๐Ÿ‡ต๐Ÿ‡ฑ', '๐Ÿ‡ต๐Ÿ‡น', '๐Ÿ‡ท๐Ÿ‡บ', '๐Ÿ‡ธ๐Ÿ‡ฆ', '๐Ÿ‡ธ๐Ÿ‡ฌ', '๐Ÿ‡ฟ๐Ÿ‡ฆ', '๐Ÿ‡ช๐Ÿ‡ธ', '๐Ÿ‡ธ๐Ÿ‡ช', '๐Ÿ‡จ๐Ÿ‡ญ', '๐Ÿ‡น๐Ÿ‡ญ', '๐Ÿ‡น๐Ÿ‡ท', '๐Ÿ‡บ๐Ÿ‡ฆ', '๐Ÿ‡ฆ๐Ÿ‡ช', '๐Ÿ‡ฌ๐Ÿ‡ง', '๐Ÿ‡บ๐Ÿ‡ธ', '๐Ÿ‡ป๐Ÿ‡ณ'] + }; + + // Global EMOJIS list for reactions (flattened) + const EMOJIS = Object.values(EMOJI_CATEGORIES).flat(); + + function populateEmojiGrid(category = null, searchTerm = '') { + const roleEmojiGrid = document.getElementById('role-emoji-grid'); + if (!roleEmojiGrid) return; + + roleEmojiGrid.innerHTML = ''; + let emojis = []; + + if (searchTerm) { + emojis = EMOJIS.filter(e => e.includes(searchTerm) || searchTerm === ''); + // For simple search by name, we'd need names, but since we only have the emoji characters, + // the user might search by the emoji itself or we could just show all if search is empty. + // Actually, without a mapping of emoji to names, searching is limited. + // But I'll implement it anyway so if they paste an emoji it works, + // or I can add common names if I had a mapping. + // Given the constraint, I'll just filter by character for now, + // or maybe the user just wants a way to filter the massive list. + } else { + emojis = EMOJI_CATEGORIES[category] || []; + } + + emojis.forEach(emoji => { + const span = document.createElement('span'); + span.textContent = emoji; + span.style.cursor = 'pointer'; + span.style.fontSize = '20px'; + span.style.padding = '5px'; + span.style.textAlign = 'center'; + span.className = 'rounded role-emoji-item'; + span.onclick = () => { + document.getElementById('edit-role-icon').value = emoji; + document.getElementById('selected-role-emoji-preview').textContent = emoji; + }; + roleEmojiGrid.appendChild(span); + }); + } + + function initEmojiCategories() { + const categoriesContainer = document.getElementById('role-emoji-categories'); + const searchInput = document.getElementById('role-emoji-search'); + if (!categoriesContainer) return; + + categoriesContainer.innerHTML = ''; + Object.keys(EMOJI_CATEGORIES).forEach((cat, index) => { + const btn = document.createElement('button'); + btn.type = 'button'; + btn.className = 'btn btn-sm btn-dark text-nowrap px-2 py-1'; + btn.style.fontSize = '0.75em'; + btn.textContent = cat; + if (index === 0) btn.classList.add('active', 'btn-primary'); + + btn.onclick = () => { + if (searchInput) searchInput.value = ''; + categoriesContainer.querySelectorAll('button').forEach(b => b.classList.remove('active', 'btn-primary')); + btn.classList.add('active', 'btn-primary'); + populateEmojiGrid(cat); + }; + categoriesContainer.appendChild(btn); + }); + + if (searchInput) { + searchInput.oninput = () => { + const term = searchInput.value.trim(); + if (term) { + categoriesContainer.querySelectorAll('button').forEach(b => b.classList.remove('active', 'btn-primary')); + populateEmojiGrid(null, term); + } else { + const activeCat = categoriesContainer.querySelector('button.active')?.textContent || Object.keys(EMOJI_CATEGORIES)[0]; + populateEmojiGrid(activeCat); + } + }; + } + + // Initial load + populateEmojiGrid(Object.keys(EMOJI_CATEGORIES)[0]); + } + + // Call init if elements exist + if (document.getElementById('role-emoji-grid')) { + initEmojiCategories(); + } // Scroll to bottom scrollToBottom(true); @@ -268,20 +363,100 @@ document.addEventListener('DOMContentLoaded', () => { function showEmojiPicker(anchor, callback) { document.querySelector('.emoji-picker')?.remove(); const picker = document.createElement('div'); - picker.className = 'emoji-picker'; - EMOJIS.forEach(emoji => { - const span = document.createElement('span'); - span.textContent = emoji; - span.onclick = () => { - callback(emoji); - picker.remove(); + picker.className = 'emoji-picker p-0 overflow-hidden d-flex flex-column'; + picker.style.width = '280px'; + picker.style.height = '320px'; + picker.style.backgroundColor = 'var(--bg-secondary)'; + picker.style.border = '1px solid var(--bg-tertiary)'; + picker.style.borderRadius = '8px'; + picker.style.boxShadow = '0 8px 24px rgba(0,0,0,0.5)'; + picker.style.zIndex = '2000'; + + const tabs = document.createElement('div'); + tabs.className = 'd-flex overflow-auto border-bottom border-secondary p-1 bg-dark'; + tabs.style.gap = '2px'; + + const searchContainer = document.createElement('div'); + searchContainer.className = 'p-2 border-bottom border-secondary'; + const searchInput = document.createElement('input'); + searchInput.type = 'text'; + searchInput.placeholder = 'Search emoji...'; + searchInput.className = 'form-control form-control-sm bg-dark border-secondary text-white'; + searchContainer.appendChild(searchInput); + + const grid = document.createElement('div'); + grid.className = 'flex-grow-1 overflow-auto p-2'; + grid.style.display = 'grid'; + grid.style.gridTemplateColumns = 'repeat(7, 1fr)'; + grid.style.gap = '2px'; + + const renderGrid = (cat = null, term = '') => { + grid.innerHTML = ''; + let emojis = []; + if (term) { + emojis = EMOJIS.filter(e => e.includes(term)); + } else { + emojis = EMOJI_CATEGORIES[cat] || []; + } + + emojis.forEach(emoji => { + const span = document.createElement('span'); + span.textContent = emoji; + span.style.cursor = 'pointer'; + span.style.fontSize = '20px'; + span.style.padding = '5px'; + span.style.textAlign = 'center'; + span.className = 'rounded role-emoji-item'; + span.onclick = () => { + callback(emoji); + picker.remove(); + }; + grid.appendChild(span); + }); + }; + + searchInput.oninput = () => { + const term = searchInput.value.trim(); + if (term) { + tabs.querySelectorAll('button').forEach(b => b.classList.remove('text-primary')); + renderGrid(null, term); + } else { + const activeCat = tabs.querySelector('button.text-primary')?.textContent || Object.keys(EMOJI_CATEGORIES)[0]; + renderGrid(activeCat); + } + }; + + Object.keys(EMOJI_CATEGORIES).forEach((cat, index) => { + const btn = document.createElement('button'); + btn.type = 'button'; + btn.className = 'btn btn-sm btn-dark text-nowrap px-2 py-1 border-0'; + btn.style.fontSize = '0.7em'; + btn.textContent = cat; + if (index === 0) btn.classList.add('text-primary'); + + btn.onclick = (e) => { + e.stopPropagation(); + searchInput.value = ''; + tabs.querySelectorAll('button').forEach(b => b.classList.remove('text-primary')); + btn.classList.add('text-primary'); + renderGrid(cat); }; - picker.appendChild(span); + tabs.appendChild(btn); }); + + picker.appendChild(tabs); + picker.appendChild(searchContainer); + picker.appendChild(grid); document.body.appendChild(picker); + + renderGrid(Object.keys(EMOJI_CATEGORIES)[0]); + const rect = anchor.getBoundingClientRect(); - picker.style.top = `${rect.top - picker.offsetHeight - 5}px`; - picker.style.left = `${rect.left}px`; + let top = rect.top - picker.offsetHeight - 5; + if (top < 0) top = rect.bottom + 5; + picker.style.position = 'fixed'; + picker.style.top = `${top}px`; + picker.style.left = `${Math.min(rect.left, window.innerWidth - 300)}px`; } function updateReactionUI(messageId, reactions) { @@ -436,7 +611,7 @@ document.addEventListener('DOMContentLoaded', () => {
${escapeHTML(msg.username)} - ${msg.role_icon ? `` : ''} + ${msg.role_icon ? `` : ''} ${msg.time}
@@ -852,7 +1027,7 @@ document.addEventListener('DOMContentLoaded', () => {
${role.name} - ${role.icon_url ? (isUrl ? `` : `${role.icon_url}`) : ''} + ${role.icon_url ? (isUrl ? `` : `${role.icon_url}`) : ''}
@@ -884,7 +1059,7 @@ document.addEventListener('DOMContentLoaded', () => { }); const isIconUrl = member.role_icon && (member.role_icon.startsWith('http') || member.role_icon.startsWith('/')); - const roleIconHtml = member.role_icon ? (isIconUrl ? `` : `${member.role_icon}`) : ''; + const roleIconHtml = member.role_icon ? (isIconUrl ? `` : `${member.role_icon}`) : ''; item.innerHTML = `
@@ -912,6 +1087,7 @@ document.addEventListener('DOMContentLoaded', () => { document.getElementById('edit-role-name').value = role.name; document.getElementById('edit-role-color').value = role.color; document.getElementById('edit-role-icon').value = role.icon; + document.getElementById('selected-role-emoji-preview').textContent = role.icon || ''; const permsContainer = document.getElementById('role-permissions-checkboxes'); permsContainer.innerHTML = ''; @@ -957,12 +1133,6 @@ document.addEventListener('DOMContentLoaded', () => { } catch (e) { console.error(e); } }); - document.getElementById('role-emoji-picker-btn')?.addEventListener('click', (e) => { - showEmojiPicker(e.currentTarget, (emoji) => { - document.getElementById('edit-role-icon').value = emoji; - }); - }); - membersList?.addEventListener('change', async (e) => { if (e.target.classList.contains('role-assign-check')) { const userId = e.target.dataset.userId; @@ -1554,7 +1724,7 @@ document.addEventListener('DOMContentLoaded', () => { 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 roleIcon = msg.role_icon ? (isRoleIconUrl ? `` : `${msg.role_icon}`) : ''; div.innerHTML = `
diff --git a/index.php b/index.php index 1246c37..7dc3c27 100644 --- a/index.php +++ b/index.php @@ -1,7 +1,7 @@ ; } + .role-emoji-item:hover { + background-color: rgba(255,255,255,0.1); + transform: scale(1.2); + transition: transform 0.1s; + } @@ -495,7 +500,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
"> - + SOLUTION @@ -601,7 +606,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
Started by "> - + โ€ข messages
@@ -631,7 +636,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
"> - + @@ -779,7 +784,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
"> - +
@@ -1285,10 +1290,20 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
- -
- - + +
+
+ + +
+
+ +
+
+ +
+
+