From e5bb5af333a305d9e4a5e25ff4c6b96fc9824eed Mon Sep 17 00:00:00 2001 From: thororen <78185467+thororen1234@users.noreply.github.com> Date: Tue, 23 Jun 2026 21:30:31 -0400 Subject: [PATCH] CharacterCounter: add selected text count (#4129) Co-authored-by: V --- src/plugins/characterCounter/index.tsx | 28 +++++++++++++++++++++----- src/plugins/characterCounter/style.css | 4 ++++ src/utils/constants.ts | 4 ++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/plugins/characterCounter/index.tsx b/src/plugins/characterCounter/index.tsx index f2826bccf..85bc21a02 100644 --- a/src/plugins/characterCounter/index.tsx +++ b/src/plugins/characterCounter/index.tsx @@ -11,7 +11,7 @@ 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 { useEffect, UserStore, useState } from "@webpack/common"; const cl = classNameFactory("vc-charCounter-"); @@ -34,7 +34,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 +42,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 +56,19 @@ 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 = () => { + setSelectedCount(document.getSelection()?.toString()?.length ?? 0); + }; + + document.addEventListener("selectionchange", listener); + return () => document.removeEventListener("selectionchange", listener); + }, []); + if (!text.length) return null; const premiumType = UserStore.getCurrentUser().premiumType ?? 0; @@ -66,6 +78,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 072d42bef..91906d6a4 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: var(--brand-500); } \ No newline at end of file diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 8629d51d4..a4ff9aa4e 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 + }, nightmaresan: { name: "NightmareSan", id: 304239816466235392n