From 7d5496e1051b7de2af89a58d9cb38ecbe4568de6 Mon Sep 17 00:00:00 2001 From: Gapodo Date: Mon, 20 Nov 2023 23:34:41 +0100 Subject: [PATCH] redo emoji --- package-lock.json | 35 ++++--- package.json | 5 +- shared/js/ui/react-elements/ChatBox.tsx | 126 +++++++++++------------- 3 files changed, 80 insertions(+), 86 deletions(-) diff --git a/package-lock.json b/package-lock.json index 543338b1..dd760333 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2834,6 +2834,7 @@ "version": "7.10.3", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.3.tgz", "integrity": "sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw==", + "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } @@ -3037,6 +3038,16 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@emoji-mart/data": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emoji-mart/data/-/data-1.1.2.tgz", + "integrity": "sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg==" + }, + "@emoji-mart/react": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emoji-mart/react/-/react-1.1.1.tgz", + "integrity": "sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g==" + }, "@google-cloud/common": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.4.0.tgz", @@ -4970,15 +4981,6 @@ "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==", "dev": true }, - "@types/emoji-mart": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@types/emoji-mart/-/emoji-mart-3.0.12.tgz", - "integrity": "sha512-ff8xM0+98PhhX15xjDseOWGDz413QvCK6D+yes88u0GJ7DoH3qR5AdMI9CbYA7/jE25WxSvX2SsGnI8Mw1Wbkw==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/emscripten": { "version": "1.39.10", "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.10.tgz", @@ -9915,13 +9917,9 @@ } }, "emoji-mart": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/emoji-mart/-/emoji-mart-3.0.1.tgz", - "integrity": "sha512-sxpmMKxqLvcscu6mFn9ITHeZNkGzIvD0BSNFE/LJESPbCA8s1jM6bCDPjWbV31xHq7JXaxgpHxLB54RCbBZSlg==", - "requires": { - "@babel/runtime": "^7.0.0", - "prop-types": "^15.6.0" - } + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/emoji-mart/-/emoji-mart-5.5.2.tgz", + "integrity": "sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A==" }, "emoji-regex": { "version": "9.2.2", @@ -19527,7 +19525,8 @@ "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true }, "regenerator-transform": { "version": "0.14.5", @@ -23899,4 +23898,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 71021666..12afd3b1 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "@svgr/webpack": "^5.5.0", "@types/dompurify": "^2.4.0", "@types/ejs": "^3.1.5", - "@types/emoji-mart": "^3.0.12", "@types/emscripten": "^1.39.10", "@types/fs-extra": "^8.1.5", "@types/html-minifier": "^3.5.3", @@ -98,6 +97,8 @@ }, "homepage": "https://www.teaspeak.de", "dependencies": { + "@emoji-mart/data": "^1.1.2", + "@emoji-mart/react": "^1.1.1", "@types/crypto-js": "^4.2.1", "broadcastchannel-polyfill": "^1.0.1", "buffer": "^6.0.3", @@ -105,7 +106,7 @@ "crypto-js": "^4.2.0", "detect-browser": "^5.3.0", "dompurify": "^2.4.7", - "emoji-mart": "^3.0.1", + "emoji-mart": "^5.5.2", "emoji-regex": "^9.2.2", "highlight.js": "^10.7.3", "ip-regex": "^4.3.0", diff --git a/shared/js/ui/react-elements/ChatBox.tsx b/shared/js/ui/react-elements/ChatBox.tsx index 8f3b2ec1..e3d133fa 100644 --- a/shared/js/ui/react-elements/ChatBox.tsx +++ b/shared/js/ui/react-elements/ChatBox.tsx @@ -1,14 +1,16 @@ import * as React from "react"; -import {useEffect, useRef, useState} from "react"; -import {Registry} from "tc-shared/events"; +import { useEffect, useRef, useState } from "react"; +import { Registry } from "tc-shared/events"; + +import { settings, Settings } from "tc-shared/settings"; +import { Translatable } from "tc-shared/ui/react-elements/i18n"; + +import Picker from '@emoji-mart/react' +import data from '@emoji-mart/data' +import { Emoji, init } from "emoji-mart"; + +init({ data }) -import '!style-loader!css-loader!emoji-mart/css/emoji-mart.css' -import {Picker, emojiIndex} from 'emoji-mart' -import {settings, Settings} from "tc-shared/settings"; -import {Translatable} from "tc-shared/ui/react-elements/i18n"; -import {getTwenmojiHashFromNativeEmoji} from "tc-shared/text/bbcode/EmojiUtil"; -import {BaseEmoji} from "emoji-mart"; -import {useGlobalSetting} from "tc-shared/ui/react-elements/Helper"; const cssStyle = require("./ChatBox.scss"); @@ -28,34 +30,27 @@ interface ChatBoxEvents { } const LastUsedEmoji = () => { - const settingValue = useGlobalSetting(Settings.KEY_CHAT_LAST_USED_EMOJI); - const lastEmoji: BaseEmoji = (emojiIndex.emojis[settingValue] || emojiIndex.emojis["joy"]) as any; - if(!lastEmoji?.native) { - return {""}; - } + return new Emoji({ id: 'smiley', set: 'native' }).component - return ( - {lastEmoji.native} - ) } const EmojiButton = (props: { events: Registry }) => { - const [ shown, setShown ] = useState(false); - const [ enabled, setEnabled ] = useState(false); + const [shown, setShown] = useState(false); + const [enabled, setEnabled] = useState(false); const refContainer = useRef(); useEffect(() => { - if(!shown) { + if (!shown) { return; } const clickListener = (event: MouseEvent) => { let target = event.target as HTMLElement; - while(target && target !== refContainer.current) + while (target && target !== refContainer.current) target = target.parentElement; - if(target === refContainer.current && target) + if (target === refContainer.current && target) return; setShown(false); @@ -76,22 +71,21 @@ const EmojiButton = (props: { events: Registry }) => {
{!shown ? undefined : { - if(enabled) { - settings.setValue(Settings.KEY_CHAT_LAST_USED_EMOJI, emoji.id as string); + onEmojiSelect={(emoji: any) => { + if (enabled) { props.events.fire("action_insert_text", { text: emoji.native, focus: true }); } }} /> + }
@@ -101,27 +95,27 @@ const EmojiButton = (props: { events: Registry }) => { const pasteTextTransformElement = document.createElement("div"); const nodeToText = (element: Node) => { - if(element instanceof Text) { + if (element instanceof Text) { return element.textContent; - } else if(element instanceof HTMLElement) { - if(element instanceof HTMLImageElement) { + } else if (element instanceof HTMLElement) { + if (element instanceof HTMLImageElement) { return element.alt || element.title; - } else if(element instanceof HTMLBRElement) { + } else if (element instanceof HTMLBRElement) { return '\n'; - } else if(element instanceof HTMLAnchorElement) { + } else if (element instanceof HTMLAnchorElement) { const content = [...element.childNodes].map(nodeToText).join(""); - if(element.href) { - if(settings.getValue(Settings.KEY_CHAT_ENABLE_MARKDOWN)) { - if(content && element.title) { + if (element.href) { + if (settings.getValue(Settings.KEY_CHAT_ENABLE_MARKDOWN)) { + if (content && element.title) { return `[${content}](${element.href} "${element.title}")`; - } else if(content) { + } else if (content) { return `[${content}](${element.href})`; } else { return `[${element.href}](${element.href})`; } - } else if(settings.getValue(Settings.KEY_CHAT_ENABLE_BBCODE)) { - if(content) { + } else if (settings.getValue(Settings.KEY_CHAT_ENABLE_BBCODE)) { + if (content) { return `[url=${element.href}]${content}"[/url]`; } else { return `[url]${element.href}"[/url]`; @@ -134,11 +128,11 @@ const nodeToText = (element: Node) => { } } - if(element.children.length > 0) { + if (element.children.length > 0) { return [...element.childNodes].map(nodeToText).join(""); } - return typeof(element.innerText) === "string" ? element.innerText : ""; + return typeof (element.innerText) === "string" ? element.innerText : ""; } else { return ""; } @@ -146,19 +140,19 @@ const nodeToText = (element: Node) => { const htmlEscape = (message: string) => { pasteTextTransformElement.innerText = message; - message = pasteTextTransformElement.innerHTML; + message = pasteTextTransformElement.innerHTML; return message.replace(/ /g, ' '); }; const TextInput = (props: { events: Registry, enabled?: boolean, placeholder?: string }) => { - const [ enabled, setEnabled ] = useState(!!props.enabled); - const [ historyIndex, setHistoryIndex ] = useState(-1); + const [enabled, setEnabled] = useState(!!props.enabled); + const [historyIndex, setHistoryIndex] = useState(-1); const history = useRef([]); const refInput = useRef(); const typingTimeout = useRef(undefined); const triggerTyping = () => { - if(typeof typingTimeout.current === "number") + if (typeof typingTimeout.current === "number") return; props.events.fire("notify_typing"); @@ -182,7 +176,7 @@ const TextInput = (props: { events: Registry, enabled?: boolean, event.preventDefault(); const clipboard = event.clipboardData || (window as any).clipboardData; - if(!clipboard) return; + if (!clipboard) return; const rawText = clipboard.getData('text/plain'); const selection = window.getSelection(); @@ -191,7 +185,7 @@ const TextInput = (props: { events: Registry, enabled?: boolean, } let htmlXML = clipboard.getData('text/html'); - if(!htmlXML) { + if (!htmlXML) { pasteTextTransformElement.textContent = rawText; htmlXML = pasteTextTransformElement.innerHTML; } @@ -235,33 +229,33 @@ const TextInput = (props: { events: Registry, enabled?: boolean, triggerTyping(); const inputEmpty = refInput.current.innerText.trim().length === 0; - if(event.key === "Enter" && !event.shiftKey) { - if(inputEmpty) { + if (event.key === "Enter" && !event.shiftKey) { + if (inputEmpty) { return; } const text = refInput.current.innerText; props.events.fire("action_submit_message", { message: text }); history.current.push(text); - while(history.current.length > 10) { + while (history.current.length > 10) { history.current.pop_front(); } refInput.current.innerText = ""; setHistoryIndex(-1); event.preventDefault(); - } else if(event.key === "ArrowUp") { + } else if (event.key === "ArrowUp") { const inputOriginal = history.current[historyIndex] === refInput.current.innerText; - if(inputEmpty && (historyIndex === -1 || !inputOriginal)) { + if (inputEmpty && (historyIndex === -1 || !inputOriginal)) { setHistory(history.current.length - 1); event.preventDefault(); - } else if(historyIndex > 0 && inputOriginal) { + } else if (historyIndex > 0 && inputOriginal) { setHistory(historyIndex - 1); event.preventDefault(); } - } else if(event.key === "ArrowDown") { - if(history.current[historyIndex] === refInput.current.innerText) { - if(historyIndex < history.current.length - 1) { + } else if (event.key === "ArrowDown") { + if (history.current[historyIndex] === refInput.current.innerText) { + if (historyIndex < history.current.length - 1) { setHistory(historyIndex + 1); } else { setHistory(-1); @@ -273,7 +267,7 @@ const TextInput = (props: { events: Registry, enabled?: boolean, props.events.reactUse("action_request_focus", () => refInput.current?.focus()); props.events.reactUse("notify_typing", () => { - if(typeof typingTimeout.current === "number") { + if (typeof typingTimeout.current === "number") { return; } @@ -281,15 +275,15 @@ const TextInput = (props: { events: Registry, enabled?: boolean, }); props.events.reactUse("action_insert_text", event => { refInput.current.innerHTML = refInput.current.innerHTML + event.text; - if(event.focus) { + if (event.focus) { refInput.current.focus(); } }); props.events.reactUse("action_set_enabled", event => { setEnabled(event.enabled); - if(!event.enabled) { + if (!event.enabled) { const text = refInput.current.innerText; - if(text.trim().length !== 0) + if (text.trim().length !== 0) history.current.push(text); refInput.current.innerText = ""; } @@ -324,17 +318,17 @@ export interface ChatBoxState { } const MarkdownFormatHelper = () => { - const [ visible, setVisible ] = useState(settings.getValue(Settings.KEY_CHAT_ENABLE_MARKDOWN)); + const [visible, setVisible] = useState(settings.getValue(Settings.KEY_CHAT_ENABLE_MARKDOWN)); settings.events.reactUse("notify_setting_changed", event => { - if(event.setting !== Settings.KEY_CHAT_ENABLE_MARKDOWN.key) { + if (event.setting !== Settings.KEY_CHAT_ENABLE_MARKDOWN.key) { return; } setVisible(settings.getValue(Settings.KEY_CHAT_ENABLE_MARKDOWN)); }); - if(visible) { + if (visible) { return (
*italic*, **bold**, ~~strikethrough~~, `code`, and more...
); @@ -380,7 +374,7 @@ export class ChatBox extends React.Component { } componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any): void { - if(prevState.enabled !== this.state.enabled) { + if (prevState.enabled !== this.state.enabled) { this.events.fire_react("action_set_enabled", { enabled: this.state.enabled }); } }