diff --git a/src/plugins/characterCounter/index.tsx b/src/plugins/characterCounter/index.tsx index f2826bccf2..666a20f5c9 100644 --- a/src/plugins/characterCounter/index.tsx +++ b/src/plugins/characterCounter/index.tsx @@ -11,9 +11,11 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { classNameFactory } from "@utils/css"; import definePlugin, { OptionType } from "@utils/types"; -import { UserStore } from "@webpack/common"; +import { findByPropsLazy } from "@webpack"; +import { useEffect, UserStore, useState } from "@webpack/common"; const cl = classNameFactory("vc-charCounter-"); +const SlateUtils = findByPropsLazy("getSelectedText"); const settings = definePluginSettings({ colorEffects: { @@ -34,7 +36,7 @@ function getCounterColor(percentage: number) { export default definePlugin({ name: "CharacterCounter", description: "Adds a character counter to the chat input", - authors: [Devs.thororen], + authors: [Devs.thororen, Devs.creations], tags: ["Utility"], settings, patches: [ @@ -42,8 +44,8 @@ export default definePlugin({ find: ".CREATE_FORUM_POST||", replacement: [ { - match: /(?<=textValue:(\i),editorHeight:\i,channelId:\i\.id\}\)),\i/, - replace: ",$self.renderCharCounter({text:$1})" + match: /(?<=,editorRef:(\i),.{0,200}textValue:(\i),editorHeight:\i,channelId:\i\.id\}\)),\i/, + replace: ",$self.renderCharCounter({editorRef:$1,text:$2})" } ] }, @@ -56,7 +58,21 @@ export default definePlugin({ } ], - renderCharCounter: ErrorBoundary.wrap(({ text }: { text: string; }) => { + renderCharCounter: ErrorBoundary.wrap(({ editorRef, text }: { text: string; editorRef: any; }) => { + const [selectedCount, setSelectedCount] = useState(0); + const showSelected = selectedCount > 0 && (editorRef?.current?.state?.focused ?? false); + + useEffect(() => { + const listener = () => { + if (!editorRef?.current) return setSelectedCount(0); + + setTimeout(() => setSelectedCount(SlateUtils.getSelectedText(editorRef.current?.getSlateEditor())?.length ?? 0), 50); + }; + + document.addEventListener("selectionchange", listener); + return () => document.removeEventListener("selectionchange", listener); + }, []); + if (!text.length) return null; const premiumType = UserStore.getCurrentUser().premiumType ?? 0; @@ -66,6 +82,12 @@ export default definePlugin({ return (
+ {showSelected && ( + <> + {selectedCount} + / + + )} {text.length} / {charMax} diff --git a/src/plugins/characterCounter/style.css b/src/plugins/characterCounter/style.css index 072d42bef4..87f7d775af 100644 --- a/src/plugins/characterCounter/style.css +++ b/src/plugins/characterCounter/style.css @@ -12,4 +12,8 @@ .vc-charCounter-count { transition: color 0.3s ease; +} + +.vc-charCounter-selected { + color: #4285F4 } \ No newline at end of file diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 61550c00a0..17dead58e8 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -638,6 +638,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ name: "prism", id: 390884143749136386n, }, + creations: { + name: "creations", + id: 209830981060788225n + }, } satisfies Record); // iife so #__PURE__ works correctly