Plugin

CharacterCounter

Adds a character counter to the chat input

Utility
index.tsx
Download

Source

src/plugins/characterCounter/index.tsx
1import "./style.css";
2
3import { definePluginSettings } from "@api/Settings";
4import ErrorBoundary from "@components/ErrorBoundary";
5import { Devs } from "@utils/constants";
6import { classNameFactory } from "@utils/css";
7import definePlugin, { OptionType } from "@utils/types";
8import { UserStore } from "@webpack/common";
9
10const cl = classNameFactory("vc-charCounter-");
11
12const settings = definePluginSettings({
13 colorEffects: {
14 type: OptionType.BOOLEAN,
15 description: "Enable yellow/red colouring as you get closer to the character limit",
16 default: true,
17 }
18});
19
20function getCounterColor(percentage: number) {
21 if (!settings.store.colorEffects) return "var(--primary-330)";
22 if (percentage < 50) return "var(--text-muted)";
23 if (percentage < 75) return "var(--yellow-330)";
24 if (percentage < 90) return "var(--orange-330)";
25 return "var(--red-360)";
26}
27
28export default definePlugin({
29 name: "CharacterCounter",
30 description: "Adds a character counter to the chat input",
31 authors: [Devs.thororen],
32 tags: ["Utility"],
33 settings,
34 patches: [
35 {
36 find: ".CREATE_FORUM_POST||",
37 replacement: [
38 {
39 match: /(?<=textValue:(\i),editorHeight:\i,channelId:\i\.id\}\)),\i/,
40 replace: ",$self.renderCharCounter({text:$1})"
41 }
42 ]
43 },
44 {
45 find: "#{intl::PREMIUM_MESSAGE_LENGTH_UPSELL_TOOLTIP}",
46 replacement: {
47 match: /(?<=\.PREMIUM_UPSELL\);)(?=.{0,50}\.PREMIUM_UPSELL_VIEWED)/,
48 replace: "return null;"
49 }
50 }
51 ],
52
53 renderCharCounter: ErrorBoundary.wrap(({ text }: { text: string; }) => {
54 if (!text.length) return null;
55
56 const premiumType = UserStore.getCurrentUser().premiumType ?? 0;
57 const charMax = premiumType === 2 ? 4000 : 2000;
58
59 const color = getCounterColor((text.length / charMax) * 100);
60
61 return (
62 <div className={cl("counter")} style={{ color }}>
63 <span className={cl("count")}>{text.length}</span>
64 /
65 <span className={cl("max")}>{charMax}</span>
66 </div>
67 );
68 }, { noop: true })
69});
70