bafplus2

Torn Chat Emoji+

Feb 19th, 2026
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JSON 15.91 KB | None | 0 0
  1. // ==UserScript==
  2. // @name         Torn Chat Emoji+
  3. // @namespace    http://tampermonkey.net/
  4. // @version      1.2
  5. // @description  Adds a categorized emoji menu with dark mode, favorites and configurable button emoji.
  6. // @author       HeyItzWerty [3626448]
  7. // @match        https://www.torn.com/*
  8. // @grant        none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12.     'use strict';
  13.  
  14.     // --- STORAGE KEYS ---
  15.     const FAVORITES_KEY = 'torn_emoji_plus_favorites';
  16.     const CUSTOM_KEY = 'torn_emoji_plus_custom';
  17.     const DARK_MODE_KEY = 'torn_emoji_plus_dark_mode';
  18.     const BUTTON_EMOJI_KEY = 'torn_emoji_plus_button_emoji';
  19.  
  20.     let favorites = JSON.parse(localStorage.getItem(FAVORITES_KEY)) || [];
  21.     let customEmojis = JSON.parse(localStorage.getItem(CUSTOM_KEY)) || [];
  22.     let isDarkMode = localStorage.getItem(DARK_MODE_KEY) === 'true';
  23.     let fixedButtonEmoji = localStorage.getItem(BUTTON_EMOJI_KEY) || '๐Ÿ˜Š';
  24.     let isSelectingButtonEmoji = false;
  25.  
  26. const emojiCategories = {
  27.     'โญ Favorites': favorites,
  28.     'โœจ My Custom Emojis': customEmojis,
  29.  
  30.     '๐Ÿ™‚ Smileys & Emotion': ['๐Ÿ˜€','๐Ÿ˜ƒ','๐Ÿ˜„','๐Ÿ˜','๐Ÿ˜†','๐Ÿ˜…','๐Ÿ˜‚','๐Ÿคฃ','๐Ÿฅฒ','๐Ÿฅน','๐Ÿ˜Š','๐Ÿ˜‡','๐Ÿ™‚','๐Ÿ™ƒ','๐Ÿ˜‰','๐Ÿ˜','๐Ÿฅฐ','๐Ÿ˜˜','๐Ÿ˜‹','๐Ÿ˜›','๐Ÿ˜œ','๐Ÿคช','๐Ÿคจ','๐Ÿง','๐Ÿค“','๐Ÿ˜Ž','๐Ÿฅธ','๐Ÿคฉ','๐Ÿฅณ','๐Ÿ˜','๐Ÿ˜’','๐Ÿ˜ž','๐Ÿ˜”','๐Ÿ˜Ÿ','๐Ÿ˜•','๐Ÿ™','โ˜น๏ธ','๐Ÿ˜ฃ','๐Ÿ˜–','๐Ÿ˜ซ','๐Ÿ˜ฉ','๐Ÿฅบ','๐Ÿ˜ข','๐Ÿ˜ญ','๐Ÿ˜ค','๐Ÿ˜ ','๐Ÿ˜ก','๐Ÿคฌ','๐Ÿคฏ','๐Ÿ˜ณ','๐Ÿฅต','๐Ÿฅถ','๐Ÿ˜ฑ','๐Ÿ˜จ','๐Ÿ˜ฐ','๐Ÿ˜ฅ','๐Ÿ˜“','๐Ÿซฃ','๐Ÿค—','๐Ÿซก','๐Ÿค”','๐Ÿซข','๐Ÿคญ','๐Ÿคซ','๐Ÿคฅ','๐Ÿ˜ถ','๐Ÿ˜ถโ€๐ŸŒซ๏ธ','๐Ÿ˜','๐Ÿ˜‘','๐Ÿ˜ฌ','๐Ÿ™„','๐Ÿ˜ฏ','๐Ÿ˜ฆ','๐Ÿ˜ง','๐Ÿ˜ฎ','๐Ÿ˜ฒ','๐Ÿฅฑ','๐Ÿ˜ด','๐Ÿคค','๐Ÿ˜ช','๐Ÿ˜ต','๐Ÿ˜ตโ€๐Ÿ’ซ','๐Ÿซฅ','๐Ÿค','๐Ÿฅด','๐Ÿคข','๐Ÿคฎ','๐Ÿคง','๐Ÿ˜ท','๐Ÿค’','๐Ÿค•','๐Ÿค‘','๐Ÿค ','๐Ÿคก','๐Ÿ’ฉ','๐Ÿ‘ป','๐ŸŽƒ','๐Ÿ˜บ','๐Ÿ˜ธ','๐Ÿ˜น','๐Ÿ˜ป','๐Ÿ˜ผ','๐Ÿ˜ฝ','๐Ÿ™€','๐Ÿ˜ฟ','๐Ÿ˜พ'],
  31.  
  32.     '๐Ÿ‘‹ People & Body': ['๐Ÿ‘‹','๐Ÿคš','๐Ÿ–๏ธ','โœ‹','๐Ÿ––','๐Ÿ‘Œ','๐ŸคŒ','๐Ÿค','โœŒ๏ธ','๐Ÿคž','๐Ÿซฐ','๐ŸคŸ','๐Ÿค˜','๐Ÿค™','๐Ÿ‘ˆ','๐Ÿ‘‰','๐Ÿ‘†','๐Ÿ–•','๐Ÿ‘‡','โ˜๏ธ','๐Ÿ‘','๐Ÿ‘Ž','โœŠ','๐Ÿ‘Š','๐Ÿค›','๐Ÿคœ','๐Ÿ‘','๐Ÿ™Œ','๐Ÿ‘','๐Ÿคฒ','๐Ÿค','๐Ÿ™','โœ๏ธ','๐Ÿ’…','๐Ÿคณ','๐Ÿ’ช','๐Ÿฆพ','๐Ÿฆฟ','๐Ÿฆต','๐Ÿฆถ','๐Ÿ‘‚','๐Ÿฆป','๐Ÿ‘ƒ','๐Ÿง ','๐Ÿซ€','๐Ÿซ','๐Ÿฆท','๐Ÿฆด','๐Ÿ‘€','๐Ÿ‘๏ธ','๐Ÿ‘…','๐Ÿ‘„','๐Ÿซฆ','๐Ÿ‘ถ','๐Ÿ‘ง','๐Ÿง’','๐Ÿ‘ฆ','๐Ÿ‘ฉ','๐Ÿง‘','๐Ÿ‘จ','๐Ÿ‘ต','๐Ÿง“','๐Ÿ‘ด','๐Ÿ‘ฎโ€โ™€๏ธ','๐Ÿ‘ฎ','๐Ÿ‘ทโ€โ™€๏ธ','๐Ÿ‘ท','๐Ÿ•ต๏ธโ€โ™€๏ธ','๐Ÿ•ต๏ธ','๐Ÿ‘ฉโ€โš•๏ธ','๐Ÿง‘โ€โš•๏ธ','๐Ÿ‘จโ€โš•๏ธ','๐Ÿ‘ฉโ€๐ŸŽ“','๐Ÿง‘โ€๐ŸŽ“','๐Ÿ‘จโ€๐ŸŽ“','๐Ÿ‘ฉโ€๐Ÿซ','๐Ÿง‘โ€๐Ÿซ','๐Ÿ‘จโ€๐Ÿซ','๐Ÿ‘ฉโ€โš–๏ธ','๐Ÿง‘โ€โš–๏ธ','๐Ÿ‘จโ€โš–๏ธ','๐Ÿ‘ฉโ€๐ŸŒพ','๐Ÿง‘โ€๐ŸŒพ','๐Ÿ‘จโ€๐ŸŒพ','๐Ÿ‘ฉโ€๐Ÿณ','๐Ÿง‘โ€๐Ÿณ','๐Ÿ‘จโ€๐Ÿณ','๐Ÿ‘ฉโ€๐Ÿ”ง','๐Ÿง‘โ€๐Ÿ”ง','๐Ÿ‘จโ€๐Ÿ”ง','๐Ÿ‘ฉโ€๐Ÿ’ป','๐Ÿง‘โ€๐Ÿ’ป','๐Ÿ‘จโ€๐Ÿ’ป','๐Ÿ‘ฉโ€๐ŸŽค','๐Ÿง‘โ€๐ŸŽค','๐Ÿ‘จโ€๐ŸŽค','๐Ÿ‘ฉโ€๐ŸŽจ','๐Ÿง‘โ€๐ŸŽจ','๐Ÿ‘จโ€๐ŸŽจ','๐Ÿ‘ฉโ€๐Ÿš€','๐Ÿง‘โ€๐Ÿš€','๐Ÿ‘จโ€๐Ÿš€','๐Ÿ‘ธ','๐Ÿคด','๐Ÿฆธโ€โ™€๏ธ','๐Ÿฆธ','๐Ÿฆนโ€โ™€๏ธ','๐Ÿฆน','๐ŸŽ…','๐Ÿคถ','๐Ÿง™โ€โ™€๏ธ','๐Ÿง™','๐Ÿงโ€โ™€๏ธ','๐Ÿง','๐Ÿง›โ€โ™€๏ธ','๐Ÿง›','๐ŸงŸโ€โ™€๏ธ','๐ŸงŸ','๐Ÿงžโ€โ™€๏ธ','๐Ÿงž','๐Ÿงœโ€โ™€๏ธ','๐Ÿงœ','๐Ÿงšโ€โ™€๏ธ','๐Ÿงš','๐Ÿ‘ผ','๐Ÿคฐ','๐Ÿคฑ','๐Ÿ™‡โ€โ™€๏ธ','๐Ÿ™‡','๐Ÿ’โ€โ™€๏ธ','๐Ÿ’','๐Ÿ™…โ€โ™€๏ธ','๐Ÿ™…','๐Ÿ™†โ€โ™€๏ธ','๐Ÿ™†','๐Ÿ™‹โ€โ™€๏ธ','๐Ÿ™‹','๐Ÿคฆโ€โ™€๏ธ','๐Ÿคฆ','๐Ÿคทโ€โ™€๏ธ','๐Ÿคท','๐Ÿ™Žโ€โ™€๏ธ','๐Ÿ™Ž','๐Ÿ™โ€โ™€๏ธ','๐Ÿ™','๐Ÿ’‡โ€โ™€๏ธ','๐Ÿ’‡','๐Ÿ’†โ€โ™€๏ธ','๐Ÿ’†','๐Ÿ’ƒ','๐Ÿ•บ','๐Ÿƒโ€โ™€๏ธ','๐Ÿƒ','๐Ÿšถโ€โ™€๏ธ','๐Ÿšถ','๐Ÿซ‚','๐Ÿ—ฃ๏ธ','๐Ÿ‘ค','๐Ÿ‘ฅ'],
  33.  
  34.     '๐Ÿป Animals': ['๐Ÿต','๐Ÿ’','๐Ÿฆ','๐Ÿฆง','๐Ÿถ','๐Ÿ•','๐Ÿฆฎ','๐Ÿ•โ€๐Ÿฆบ','๐Ÿฉ','๐Ÿบ','๐ŸฆŠ','๐Ÿฆ','๐Ÿฑ','๐Ÿˆ','๐Ÿˆโ€โฌ›','๐Ÿฆ','๐Ÿฏ','๐Ÿ…','๐Ÿ†','๐Ÿด','๐ŸŽ','๐Ÿฆ„','๐Ÿฆ“','๐ŸฆŒ','๐Ÿฆฌ','๐Ÿฎ','๐Ÿ‚','๐Ÿƒ','๐Ÿ„','๐Ÿท','๐Ÿ–','๐Ÿ—','๐Ÿฝ','๐Ÿ','๐Ÿ‘','๐Ÿ','๐Ÿช','๐Ÿซ','๐Ÿฆ™','๐Ÿฆ’','๐Ÿ˜','๐Ÿฆฃ','๐Ÿฆ','๐Ÿฆ›','๐Ÿญ','๐Ÿ','๐Ÿ€','๐Ÿน','๐Ÿฐ','๐Ÿ‡','๐Ÿฟ๏ธ','๐Ÿฆซ','๐Ÿฆ”','๐Ÿฆ‡','๐Ÿป','๐Ÿปโ€โ„๏ธ','๐Ÿจ','๐Ÿผ','๐Ÿฆฅ','๐Ÿฆฆ','๐Ÿฆจ','๐Ÿฆ˜','๐Ÿฆก','๐Ÿพ','๐Ÿฆƒ','๐Ÿ”','๐Ÿ“','๐Ÿฃ','๐Ÿค','๐Ÿฅ','๐Ÿฆ','๐Ÿง','๐Ÿ•Š๏ธ','๐Ÿฆ…','๐Ÿฆ†','๐Ÿฆข','๐Ÿฆ‰','๐Ÿฆค','๐Ÿชถ','๐Ÿธ','๐ŸŠ','๐Ÿข','๐ŸฆŽ','๐Ÿ','๐Ÿฒ','๐Ÿ‰','๐Ÿณ','๐Ÿ‹','๐Ÿฌ','๐Ÿฆญ','๐ŸŸ','๐Ÿ ','๐Ÿก','๐Ÿฆˆ','๐Ÿ™','๐Ÿš','๐ŸŒ','๐Ÿฆ‹','๐Ÿ›','๐Ÿœ','๐Ÿ','๐Ÿชฒ','๐Ÿž','๐Ÿฆ—','๐Ÿชณ','๐Ÿ•ท๏ธ','๐Ÿ•ธ๏ธ','๐Ÿฆ‚','๐ŸฆŸ','๐Ÿชฐ','๐Ÿชฑ'],
  35.  
  36.     '๐ŸŒณ Nature': ['๐Ÿ’','๐ŸŒธ','๐Ÿ’ฎ','๐Ÿต๏ธ','๐ŸŒน','๐Ÿฅ€','๐ŸŒบ','๐ŸŒป','๐ŸŒผ','๐ŸŒท','๐ŸŒฑ','๐Ÿชด','๐ŸŒฒ','๐ŸŒณ','๐ŸŒด','๐Ÿชต','๐ŸŒต','๐ŸŒพ','๐ŸŒฟ','โ˜˜๏ธ','๐Ÿ€','๐Ÿ','๐Ÿ‚','๐Ÿƒ','๐ŸŒ','๐ŸŒŽ','๐ŸŒ','๐ŸŒ•','๐ŸŒ–','๐ŸŒ—','๐ŸŒ˜','๐ŸŒ‘','๐ŸŒ’','๐ŸŒ“','๐ŸŒ”','๐ŸŒ™','โญ','๐ŸŒŸ','๐Ÿ’ซ','โœจ','โ˜„๏ธ','โ˜€๏ธ','๐ŸŒค๏ธ','โ›…','๐ŸŒฅ๏ธ','๐ŸŒฆ๏ธ','โ˜๏ธ','๐ŸŒง๏ธ','โ›ˆ๏ธ','๐ŸŒฉ๏ธ','โšก','๐Ÿ”ฅ','๐Ÿ’ฅ','โ„๏ธ','๐ŸŒจ๏ธ','โ˜ƒ๏ธ','โ›„','๐ŸŒฌ๏ธ','๐Ÿ’จ','๐ŸŒช๏ธ','๐ŸŒซ๏ธ','๐ŸŒŠ','๐Ÿ’ง','๐Ÿ’ฆ'],
  37.  
  38.     '๐Ÿ” Food & Drink': ['๐Ÿ‡','๐Ÿˆ','๐Ÿ‰','๐ŸŠ','๐Ÿ‹','๐ŸŒ','๐Ÿ','๐Ÿฅญ','๐ŸŽ','๐Ÿ','๐Ÿ','๐Ÿ‘','๐Ÿ’','๐Ÿ“','๐Ÿซ','๐Ÿฅ','๐Ÿ…','๐Ÿซ’','๐Ÿฅฅ','๐Ÿฅ‘','๐Ÿ†','๐Ÿฅ”','๐Ÿฅ•','๐ŸŒฝ','๐ŸŒถ๏ธ','๐Ÿซ‘','๐Ÿฅ’','๐Ÿฅฌ','๐Ÿฅฆ','๐Ÿง„','๐Ÿง…','๐Ÿ„','๐Ÿฅœ','๐Ÿซ˜','๐ŸŒฐ','๐Ÿž','๐Ÿฅ','๐Ÿฅ–','๐Ÿซ“','๐Ÿฅจ','๐Ÿฅฏ','๐Ÿฅž','๐Ÿง‡','๐Ÿง€','๐Ÿ–','๐Ÿ—','๐Ÿฅฉ','๐Ÿฅ“','๐Ÿ”','๐ŸŸ','๐Ÿ•','๐ŸŒญ','๐Ÿฅช','๐Ÿฅ™','๐Ÿง†','๐ŸŒฎ','๐ŸŒฏ','๐Ÿซ”','๐Ÿฅ—','๐Ÿฅ˜','๐Ÿซ•','๐Ÿฅซ','๐Ÿ','๐Ÿœ','๐Ÿฒ','๐Ÿ›','๐Ÿฃ','๐Ÿฑ','๐ŸฅŸ','๐Ÿฆช','๐Ÿค','๐Ÿ™','๐Ÿš','๐Ÿ˜','๐Ÿฅ','๐Ÿฅ ','๐Ÿฅฎ','๐Ÿข','๐Ÿก','๐Ÿง','๐Ÿจ','๐Ÿฆ','๐Ÿฅง','๐Ÿง','๐Ÿฐ','๐ŸŽ‚','๐Ÿฎ','๐Ÿญ','๐Ÿฌ','๐Ÿซ','๐Ÿฟ','๐Ÿฉ','๐Ÿช','๐Ÿฏ','๐Ÿฅ›','๐Ÿผ','โ˜•๏ธ','๐Ÿซ–','๐Ÿต','๐Ÿถ','๐Ÿพ','๐Ÿท','๐Ÿธ','๐Ÿน','๐Ÿบ','๐Ÿป','๐Ÿฅ‚','๐Ÿฅƒ','๐Ÿซ—','๐Ÿฅค','๐Ÿง‹','๐Ÿงƒ','๐Ÿง‰','๐ŸงŠ','๐Ÿฅข','๐Ÿฝ๏ธ','๐Ÿด','๐Ÿฅ„','๐Ÿบ'],
  39.  
  40.     'โšฝ Activities & Events': ['โšฝ','๐Ÿ€','๐Ÿˆ','โšพ','๐ŸฅŽ','๐ŸŽพ','๐Ÿ','๐Ÿ‰','๐Ÿฅ','๐ŸŽฑ','๐Ÿช€','๐Ÿ“','๐Ÿธ','๐Ÿ’','๐Ÿ‘','๐Ÿฅ','๐Ÿ','๐Ÿชƒ','๐Ÿฅ…','โ›ณ','๐Ÿช','๐Ÿน','๐ŸŽฃ','๐Ÿคฟ','๐ŸฅŠ','๐Ÿฅ‹','๐ŸŽฝ','๐Ÿ›น','๐Ÿ›ผ','๐Ÿ›ท','โ›ธ๏ธ','๐ŸฅŒ','๐ŸŽฟ','โ›ท๏ธ','๐Ÿ‚','๐Ÿช‚','๐Ÿ‹๏ธโ€โ™€๏ธ','๐Ÿ‹๏ธ','๐Ÿ‹๏ธโ€โ™‚๏ธ','๐Ÿคผโ€โ™€๏ธ','๐Ÿคผ','๐Ÿคผโ€โ™‚๏ธ','๐Ÿคธโ€โ™€๏ธ','๐Ÿคธ','๐Ÿคธโ€โ™‚๏ธ','โ›น๏ธโ€โ™€๏ธ','โ›น๏ธ','โ›น๏ธโ€โ™‚๏ธ','๐Ÿคบ','๐Ÿคพโ€โ™€๏ธ','๐Ÿคพ','๐Ÿคพโ€โ™‚๏ธ','๐ŸŒ๏ธโ€โ™€๏ธ','๐ŸŒ๏ธ','๐ŸŒ๏ธโ€โ™‚๏ธ','๐Ÿ‡','๐Ÿง˜โ€โ™€๏ธ','๐Ÿง˜','๐Ÿง˜โ€โ™‚๏ธ','๐Ÿ„โ€โ™€๏ธ','๐Ÿ„','๐Ÿ„โ€โ™‚๏ธ','๐ŸŠโ€โ™€๏ธ','๐ŸŠ','๐ŸŠโ€โ™‚๏ธ','๐Ÿคฝโ€โ™€๏ธ','๐Ÿคฝ','๐Ÿคฝโ€โ™‚๏ธ','๐Ÿšฃโ€โ™€๏ธ','๐Ÿšฃ','๐Ÿšฃโ€โ™‚๏ธ','๐Ÿง—โ€โ™€๏ธ','๐Ÿง—','๐Ÿง—โ€โ™‚๏ธ','๐Ÿšตโ€โ™€๏ธ','๐Ÿšต','๐Ÿšตโ€โ™‚๏ธ','๐Ÿšดโ€โ™€๏ธ','๐Ÿšด','๐Ÿšดโ€โ™‚๏ธ','๐Ÿ†','๐Ÿฅ‡','๐Ÿฅˆ','๐Ÿฅ‰','๐Ÿ…','๐ŸŽ–๏ธ','๐Ÿต๏ธ','๐ŸŽ—๏ธ','๐ŸŽซ','๐ŸŽŸ๏ธ','๐ŸŽช','๐Ÿคน','๐Ÿคนโ€โ™‚๏ธ','๐Ÿคนโ€โ™€๏ธ','๐ŸŽญ','๐Ÿฉฐ','๐ŸŽจ','๐ŸŽฌ','๐ŸŽค','๐ŸŽง','๐ŸŽผ','๐ŸŽน','๐Ÿฅ','๐Ÿช˜','๐ŸŽท','๐ŸŽบ','๐Ÿช—','๐ŸŽธ','๐Ÿช•','๐ŸŽป','๐Ÿชˆ','๐ŸŽฒ','โ™Ÿ๏ธ','๐ŸŽฏ','๐ŸŽณ','๐ŸŽฎ','๐ŸŽฐ','๐Ÿงฉ','๐ŸŽ„','๐ŸŽ†','๐ŸŽ‡','๐ŸŽˆ','๐ŸŽ‰','๐ŸŽŠ','๐ŸŽ'],
  41.  
  42.     '๐Ÿ’ก Objects': ['โŒš','๐Ÿ“ฑ','๐Ÿ“ฒ','๐Ÿ’ป','โŒจ๏ธ','๐Ÿ–ฅ๏ธ','๐Ÿ–จ๏ธ','๐Ÿ–ฑ๏ธ','๐Ÿ–ฒ๏ธ','๐Ÿ•น๏ธ','๐Ÿ’ฝ','๐Ÿ’พ','๐Ÿ’ฟ','๐Ÿ“€','๐Ÿ“ผ','๐Ÿ“ท','๐Ÿ“ธ','๐Ÿ“น','๐ŸŽฅ','๐Ÿ“ž','โ˜Ž๏ธ','๐Ÿ“Ÿ','๐Ÿ“ ','๐Ÿ“บ','๐Ÿ“ป','๐ŸŽ™๏ธ','๐Ÿ’ก','๐Ÿ”ฆ','๐Ÿ•ฏ๏ธ','๐Ÿ’ฐ','๐Ÿ’ต','๐Ÿ’ด','๐Ÿ’ถ','๐Ÿ’ท','๐Ÿช™','๐Ÿ’ณ','๐Ÿ’Ž','โš–๏ธ','๐Ÿ”ง','๐Ÿ”จ','โš’๏ธ','๐Ÿ› ๏ธ','โ›๏ธ','๐Ÿ”ฉ','โš™๏ธ','๐Ÿงฑ','โ›“๏ธ','๐Ÿงฒ','โšฐ๏ธ','๐Ÿชฆ','โšฑ๏ธ','๐Ÿ”ฎ','๐Ÿ“ฟ','๐Ÿงฟ','๐Ÿ’ˆ','๐Ÿ”ญ','๐Ÿ”ฌ','๐Ÿ•ณ๏ธ','๐Ÿฉน','๐Ÿฉบ','๐Ÿงฌ','๐Ÿฆ ','๐Ÿงช','๐ŸŒก๏ธ','๐Ÿงน','๐Ÿงบ','๐Ÿšฝ','๐Ÿšฐ','๐Ÿšฟ','๐Ÿ›','๐Ÿงผ','๐Ÿชฅ','๐Ÿงฝ','๐Ÿงฏ','๐Ÿ”‘','๐Ÿ—๏ธ','๐Ÿšช','๐Ÿ›‹๏ธ','๐Ÿ›๏ธ','๐Ÿงธ','๐Ÿ–ผ๏ธ','๐Ÿ›๏ธ','๐Ÿ›’','โœ‰๏ธ','๐Ÿงง','๐Ÿ“ซ','๐Ÿ“ฎ','๐Ÿ“ฆ','๐Ÿท๏ธ','๐Ÿ“œ','๐Ÿ“ƒ','๐Ÿ“„','๐Ÿ“‘','๐Ÿ“Š','๐Ÿ“ˆ','๐Ÿ“‰','๐Ÿ—’๏ธ','๐Ÿ—“๏ธ','๐Ÿ—‘๏ธ','๐Ÿ“','๐Ÿ“‚','โœ‚๏ธ','๐Ÿ–Š๏ธ','โœ’๏ธ','๐Ÿ–Œ๏ธ','๐Ÿ–๏ธ','๐Ÿ“','โœ๏ธ','๐Ÿ”','๐Ÿ”Ž','๐Ÿ”’','๐Ÿ”','๐Ÿ”“','๐Ÿ”'],
  43.  
  44.     '๐Ÿ”ž Torn-Themed': ['๐Ÿ”ซ','๐Ÿ’ฃ','๐Ÿงจ','๐Ÿช“','๐Ÿ”ช','๐Ÿ—ก๏ธ','โš”๏ธ','๐Ÿ›ก๏ธ','๐Ÿšฌ','๐Ÿ’Š','๐Ÿ’‰','๐Ÿฉธ','โค๏ธโ€๐Ÿ”ฅ','โค๏ธโ€๐Ÿฉน','๐Ÿ’‹','๐Ÿ’ฏ','๐Ÿ’ข','๐Ÿ’ฆ','๐Ÿ†','๐Ÿ‘','๐Ÿ˜ˆ','๐Ÿ‘ฟ','๐Ÿ‘น','๐Ÿ‘บ','๐Ÿ”ฅ','๐Ÿ’ฅ','๐Ÿ’จ','๐Ÿ’ธ','โš—๏ธ','๐Ÿ”ž'],
  45.  
  46.     'โค๏ธโ€ Symbols & Flags': ['๐Ÿ†”','โš›๏ธ','โ˜ข๏ธ','โ˜ฃ๏ธ','๐Ÿ“ด','๐Ÿ†š','๐Ÿ‰‘','ใŠ—๏ธ','ใŠ™๏ธ','๐Ÿ‰','๐Ÿ†˜','โ›”','๐Ÿšซ','โŒ','โญ•','๐Ÿ›‘','๐Ÿ“›','โ™จ๏ธ','โ—๏ธ','โ•','โ“','โ”','โ€ผ๏ธ','โ‰๏ธ','โœ…','โœ”๏ธ','โ˜‘๏ธ','โŽ','โœ๏ธ','โ˜ช๏ธ','๐Ÿ•‰๏ธ','โœก๏ธ','โ˜ฏ๏ธ','โ˜ฎ๏ธ','โ˜ฆ๏ธ','โš ๏ธ','๐Ÿšธ','โ™ป๏ธ','โšœ๏ธ','๐Ÿ”ฑ','๐Ÿ”ฐ','๐Ÿง','โ™ฟ','๐Ÿ…ฟ๏ธ','๐Ÿšพ','๐Ÿ“ถ','๐Ÿˆ','๐Ÿˆ‚๏ธ','๐Ÿˆš','๐Ÿˆฏ','๐Ÿ‰','๐Ÿˆน','๐Ÿˆบ','๐Ÿˆถ','๐Ÿˆท๏ธ','๐Ÿˆธ','๐Ÿˆฒ','๐Ÿˆต','๐Ÿˆด','๐Ÿ†Ž','๐Ÿ…ฑ๏ธ','๐Ÿ…ฐ๏ธ','๐Ÿ…พ๏ธ','๐Ÿ†‘','๐Ÿ†’','๐Ÿ†“','๐Ÿ†•','๐Ÿ†–','๐Ÿ†—','๐Ÿ†™','โ†”๏ธ','โ†•๏ธ','โ†–๏ธ','โ†—๏ธ','โ†˜๏ธ','โ†™๏ธ','โ†ฉ๏ธ','โ†ช๏ธ','โคด๏ธ','โคต๏ธ','โžก๏ธ','โฌ…๏ธ','โฌ†๏ธ','โฌ‡๏ธ','โž•','โž–','โž—','โœ–๏ธ','โ™พ๏ธ','๐Ÿ’ฒ','๐Ÿ’ฑ','โ„ข๏ธ','ยฉ๏ธ','ยฎ๏ธ','๐Ÿ”š','๐Ÿ”™','๐Ÿ”›','๐Ÿ”','๐Ÿ”œ','๐Ÿ”ด','๐ŸŸ ','๐ŸŸก','๐ŸŸข','๐Ÿ”ต','๐ŸŸฃ','๐ŸŸค','โšซ','โšช','๐ŸŸฅ','๐ŸŸง','๐ŸŸจ','๐ŸŸฉ','๐ŸŸฆ','๐ŸŸช','๐ŸŸซ','โฌ›','โฌœ','๐Ÿ','๐Ÿšฉ','๐ŸŽŒ','๐Ÿด','๐Ÿณ๏ธ','๐Ÿณ๏ธโ€๐ŸŒˆ','๐Ÿณ๏ธโ€โšง๏ธ','๐Ÿดโ€โ˜ ๏ธ']
  47. };
  48.  
  49.  
  50.     const themes = {
  51.         light: { bg: '#f2f2f2', text: '#000', border: '#ccc', catBg: '#e9e9e9' },
  52.         dark:  { bg: '#2c2c2c', text: '#f1f1f1', border: '#555', catBg: '#222' }
  53.     };
  54.  
  55.     const nativeTextareaValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
  56.  
  57.     function simulateUserInput(textarea, text) {
  58.         const start = textarea.selectionStart;
  59.         const end = textarea.selectionEnd;
  60.         const newText = textarea.value.substring(0, start) + text + textarea.value.substring(end);
  61.         nativeTextareaValueSetter.call(textarea, newText);
  62.         textarea.dispatchEvent(new Event('input', { bubbles: true }));
  63.         textarea.selectionStart = textarea.selectionEnd = start + text.length;
  64.         textarea.focus();
  65.     }
  66.  
  67.     function save(key, data) {
  68.         localStorage.setItem(key, JSON.stringify(data));
  69.     }
  70.  
  71.     function showNotification(message) {
  72.         const notif = document.createElement('div');
  73.         notif.textContent = message;
  74.         Object.assign(notif.style, {
  75.             position: 'fixed', top: '20px', right: '20px',
  76.             background: 'rgba(0,0,0,0.7)', color: 'white',
  77.             padding: '10px 20px', borderRadius: '5px', zIndex: 9999
  78.         });
  79.         document.body.appendChild(notif);
  80.         setTimeout(() => notif.remove(), 1500);
  81.     }
  82.  
  83.     function addEmojiButtonTo(chatContainer) {
  84.         if (chatContainer.querySelector('.custom-emoji-button-v3')) return;
  85.  
  86.         const emojiButton = document.createElement('button');
  87.         emojiButton.className = 'custom-emoji-button-v3';
  88.         emojiButton.textContent = fixedButtonEmoji;
  89.         Object.assign(emojiButton.style, {
  90.             background: 'transparent',
  91.             border: 'none',
  92.             fontSize: '22px',
  93.             cursor: 'pointer',
  94.             height: '32px',
  95.             width: '32px',
  96.             marginRight: '5px'
  97.         });
  98.  
  99.         const picker = document.createElement('div');
  100.         Object.assign(picker.style, {
  101.             position: 'absolute', display: 'none',
  102.             bottom: '40px', left: '0',
  103.             width: '300px', height: '320px',
  104.             borderRadius: '8px', zIndex: 1001,
  105.             boxShadow: '0 5px 15px rgba(0,0,0,0.3)',
  106.             display: 'flex', flexDirection: 'column'
  107.         });
  108.  
  109.         const categoryContainer = document.createElement('div');
  110.         Object.assign(categoryContainer.style, {
  111.             display: 'flex', flexWrap: 'wrap',
  112.             padding: '5px', alignItems: 'center'
  113.         });
  114.  
  115.         const emojiDisplay = document.createElement('div');
  116.         Object.assign(emojiDisplay.style, {
  117.             padding: '5px', flexGrow: '1', overflowY: 'auto'
  118.         });
  119.  
  120.         picker.append(categoryContainer, emojiDisplay);
  121.  
  122.         function applyTheme() {
  123.             const theme = isDarkMode ? themes.dark : themes.light;
  124.             Object.assign(picker.style, {
  125.                 background: theme.bg,
  126.                 border: `1px solid ${theme.border}`,
  127.                 color: theme.text
  128.             });
  129.             categoryContainer.style.background = theme.catBg;
  130.         }
  131.  
  132.         function renderEmojis(list) {
  133.             emojiDisplay.innerHTML = '';
  134.             const grid = document.createElement('div');
  135.             Object.assign(grid.style, { display: 'flex', flexWrap: 'wrap' });
  136.  
  137.             list.forEach(emoji => {
  138.                 const span = document.createElement('span');
  139.                 span.textContent = emoji;
  140.                 Object.assign(span.style, {
  141.                     cursor: 'pointer', padding: '4px', fontSize: '22px'
  142.                 });
  143.  
  144.                 span.addEventListener('click', () => {
  145.                     if (isSelectingButtonEmoji) {
  146.                         fixedButtonEmoji = emoji;
  147.                         localStorage.setItem(BUTTON_EMOJI_KEY, emoji);
  148.                         emojiButton.textContent = emoji;
  149.                         isSelectingButtonEmoji = false;
  150.                         showNotification(`Button emoji set to ${emoji}`);
  151.                         return;
  152.                     }
  153.                     simulateUserInput(chatContainer.querySelector('textarea.textarea___V8HsV'), emoji);
  154.                     picker.style.display = 'none';
  155.                 });
  156.  
  157.                 grid.appendChild(span);
  158.             });
  159.  
  160.             emojiDisplay.appendChild(grid);
  161.         }
  162.  
  163.         Object.keys(emojiCategories).forEach(name => {
  164.             const tab = document.createElement('button');
  165.             tab.textContent = name.split(' ')[0];
  166.             Object.assign(tab.style, {
  167.                 background: 'none', border: 'none',
  168.                 cursor: 'pointer', fontSize: '20px', padding: '5px'
  169.             });
  170.             tab.addEventListener('click', () => renderEmojis(emojiCategories[name]));
  171.             categoryContainer.appendChild(tab);
  172.         });
  173.  
  174.         const themeToggle = document.createElement('button');
  175.         themeToggle.textContent = '๐ŸŒ™';
  176.         Object.assign(themeToggle.style, {
  177.             border: '1px solid', borderRadius: '5px',
  178.             cursor: 'pointer', fontSize: '16px',
  179.             width: '30px', height: '30px', marginLeft: 'auto'
  180.         });
  181.  
  182.         themeToggle.addEventListener('click', () => {
  183.             isDarkMode = !isDarkMode;
  184.             localStorage.setItem(DARK_MODE_KEY, isDarkMode);
  185.             applyTheme();
  186.         });
  187.  
  188.         const settingsBtn = document.createElement('button');
  189.         settingsBtn.textContent = 'โš™๏ธ';
  190.         settingsBtn.title = 'Set button emoji';
  191.         Object.assign(settingsBtn.style, {
  192.             border: '1px solid', borderRadius: '5px',
  193.             cursor: 'pointer', fontSize: '16px',
  194.             width: '30px', height: '30px', marginLeft: '5px'
  195.         });
  196.  
  197.         settingsBtn.addEventListener('click', () => {
  198.             isSelectingButtonEmoji = true;
  199.             showNotification('Click an emoji to set as button icon');
  200.         });
  201.  
  202.         categoryContainer.append(themeToggle, settingsBtn);
  203.  
  204.         emojiButton.addEventListener('click', (e) => {
  205.             e.stopPropagation();
  206.             picker.style.display = picker.style.display === 'none' ? 'flex' : 'none';
  207.             applyTheme();
  208.             renderEmojis(emojiCategories['๐Ÿ™‚ Smileys & Emotion']);
  209.         });
  210.  
  211.         chatContainer.insertBefore(emojiButton, chatContainer.querySelector('.iconWrapper___tyRRU'));
  212.         chatContainer.appendChild(picker);
  213.     }
  214.  
  215.     document.addEventListener('click', (e) => {
  216.         if (!e.target.closest('.custom-emoji-picker') && !e.target.closest('.custom-emoji-button-v3')) {
  217.             document.querySelectorAll('.custom-emoji-picker').forEach(p => p.style.display = 'none');
  218.         }
  219.     });
  220.  
  221.     const observer = new MutationObserver(() => {
  222.         document.querySelectorAll('.root___WUd1h').forEach(container => addEmojiButtonTo(container));
  223.     });
  224.  
  225.     observer.observe(document.body, { childList: true, subtree: true });
  226.  
  227. })();
  228.  
Advertisement
Add Comment
Please, Sign In to add comment