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