mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-13 08:33:01 -04:00
plugin: SplitLargeMessages (#249)
* add(SplitLargeMessages) * Fixes * Update README.md --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
6f422545eb
commit
0d09c083c6
3 changed files with 163 additions and 2 deletions
|
@ -11,7 +11,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
### Extra included plugins
|
### Extra included plugins
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>169 additional plugins</summary>
|
<summary>170 additional plugins</summary>
|
||||||
|
|
||||||
### All Platforms
|
### All Platforms
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
- JumpToStart by Samwich
|
- JumpToStart by Samwich
|
||||||
- KeyboardSounds by HypedDomi
|
- KeyboardSounds by HypedDomi
|
||||||
- KeywordNotify by camila314 & x3rt
|
- KeywordNotify by camila314 & x3rt
|
||||||
|
- - LastActive by Crxa
|
||||||
- LimitMiddleClickPaste by no dev listed
|
- LimitMiddleClickPaste by no dev listed
|
||||||
- LoginWithQR by nexpid
|
- LoginWithQR by nexpid
|
||||||
- MediaPlaybackSpeed by D3SOX
|
- MediaPlaybackSpeed by D3SOX
|
||||||
|
@ -142,6 +143,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
- Signature by Ven, Rini, ImBanana, KrystalSkull
|
- Signature by Ven, Rini, ImBanana, KrystalSkull
|
||||||
- Slap by Korbo
|
- Slap by Korbo
|
||||||
- SoundBoardLogger by Moxxie, fres, echo, maintained by thororen
|
- SoundBoardLogger by Moxxie, fres, echo, maintained by thororen
|
||||||
|
- - SplitLargeMessages by Reycko
|
||||||
- SpotifyLyrics by Joona
|
- SpotifyLyrics by Joona
|
||||||
- StatsfmPresence by Crxa
|
- StatsfmPresence by Crxa
|
||||||
- StatusPresets by iamme
|
- StatusPresets by iamme
|
||||||
|
@ -177,7 +179,6 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
- Woof by Samwich
|
- Woof by Samwich
|
||||||
- WriteUpperCase by Samwich & KrystalSkull
|
- WriteUpperCase by Samwich & KrystalSkull
|
||||||
- YoutubeDescription by arHSM
|
- YoutubeDescription by arHSM
|
||||||
- LastActive by Crxa
|
|
||||||
|
|
||||||
### Web Only
|
### Web Only
|
||||||
|
|
||||||
|
|
156
src/equicordplugins/splitLargeMessages/index.ts
Normal file
156
src/equicordplugins/splitLargeMessages/index.ts
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { addMessagePreSendListener, MessageSendListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
||||||
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { EquicordDevs } from "@utils/constants";
|
||||||
|
import { getCurrentChannel, sendMessage } from "@utils/discord";
|
||||||
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { ChannelStore, ComponentDispatch, PermissionsBits, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
|
let maxLength: number = 0;
|
||||||
|
|
||||||
|
const canSplit: () => boolean = () => {
|
||||||
|
const slowmode = getCurrentChannel()?.rateLimitPerUser ?? 0;
|
||||||
|
return (settings.store.splitInSlowmode ? slowmode < settings.store.slowmodeMax : slowmode <= 0) && settings.store.disableFileConversion;
|
||||||
|
};
|
||||||
|
|
||||||
|
const autoMaxLength = () => {
|
||||||
|
const hasNitro = UserStore.getCurrentUser().premiumType === 2;
|
||||||
|
return hasNitro ? 4000 : 2000;
|
||||||
|
};
|
||||||
|
|
||||||
|
const split = async (channelId: string, chunks: string[], delayInMs: number) => {
|
||||||
|
const sendChunk = async (chunk: string) => {
|
||||||
|
await sendMessage(channelId, { content: chunk }, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send the chunks
|
||||||
|
for (let i = 0; i < chunks.length; i++) {
|
||||||
|
await sendChunk(chunks[i]);
|
||||||
|
if (i < chunks.length - 1) // Not the last chunk
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delayInMs)); // Wait for `delayInMs`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const listener: MessageSendListener = async (channelId, msg) => {
|
||||||
|
if (msg.content.trim().length < maxLength || !canSplit()) return; // Nothing to split
|
||||||
|
|
||||||
|
const channel = ChannelStore.getChannel(channelId);
|
||||||
|
|
||||||
|
// Check for slowmode
|
||||||
|
let isSlowmode = channel.rateLimitPerUser > 0;
|
||||||
|
if ((channel.accessPermissions & PermissionsBits.MANAGE_MESSAGES) === PermissionsBits.MANAGE_MESSAGES
|
||||||
|
|| (channel.accessPermissions & PermissionsBits.MANAGE_CHANNELS) === PermissionsBits.MANAGE_CHANNELS)
|
||||||
|
isSlowmode = false;
|
||||||
|
|
||||||
|
// Not slowmode or splitInSlowmode is on and less than slowmodeMax
|
||||||
|
if (!isSlowmode || (settings.store.splitInSlowmode && channel.rateLimitPerUser < settings.store.slowmodeMax)) {
|
||||||
|
const chunks: string[] = [];
|
||||||
|
const { hardSplit } = settings.store;
|
||||||
|
while (msg.content.length > maxLength) {
|
||||||
|
msg.content = msg.content.trim();
|
||||||
|
|
||||||
|
// Get last space or newline
|
||||||
|
const splitIndex = Math.max(msg.content.lastIndexOf(" ", maxLength), msg.content.lastIndexOf("\n", maxLength));
|
||||||
|
|
||||||
|
// If hard split is on or neither newline or space found, split at maxLength
|
||||||
|
if (hardSplit || splitIndex === -1) {
|
||||||
|
chunks.push(msg.content.slice(0, maxLength));
|
||||||
|
msg.content = msg.content.slice(maxLength);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chunks.push(msg.content.slice(0, splitIndex));
|
||||||
|
msg.content = msg.content.slice(splitIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentDispatch.dispatchToLastSubscribed("CLEAR_TEXT");
|
||||||
|
await split(channelId, [...chunks, msg.content], settings.store.sendDelay * 1000);
|
||||||
|
}
|
||||||
|
return { cancel: true };
|
||||||
|
};
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
maxLength: {
|
||||||
|
type: OptionType.NUMBER,
|
||||||
|
description: "Maximum length of a message before it is split. Set to 0 to automatically detect.",
|
||||||
|
default: 0,
|
||||||
|
max: 4000,
|
||||||
|
onChange(newValue) {
|
||||||
|
if (newValue === 0)
|
||||||
|
maxLength = autoMaxLength();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
disableFileConversion: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "If true, disables file conversion for large messages.",
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
sendDelay: {
|
||||||
|
type: OptionType.SLIDER,
|
||||||
|
description: "Delay between each chunk in seconds.",
|
||||||
|
default: 1,
|
||||||
|
markers: [1, 2, 3, 5, 10],
|
||||||
|
},
|
||||||
|
|
||||||
|
hardSplit: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "If true, splits on the last character instead of the last space/newline.",
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
splitInSlowmode: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Should messages be split if the channel has slowmode enabled?",
|
||||||
|
},
|
||||||
|
|
||||||
|
slowmodeMax: {
|
||||||
|
type: OptionType.NUMBER,
|
||||||
|
description: "Maximum slowmode time if splitting in slowmode.",
|
||||||
|
default: 5,
|
||||||
|
min: 1,
|
||||||
|
max: 30,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "SplitLargeMessages",
|
||||||
|
description: "Splits large messages into multiple to fit Discord's message limit.",
|
||||||
|
authors: [EquicordDevs.Reycko],
|
||||||
|
dependencies: ["MessageEventsAPI"],
|
||||||
|
settings,
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (settings.store.maxLength === 0)
|
||||||
|
maxLength = autoMaxLength();
|
||||||
|
addMessagePreSendListener(listener);
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
removeMessagePreSendListener(listener);
|
||||||
|
},
|
||||||
|
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: 'type:"MESSAGE_LENGTH_UPSELL"', // bypass message length check
|
||||||
|
replacement: {
|
||||||
|
match: /if\(\i.length>\i/,
|
||||||
|
replace: "if(false",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
find: '(this,"hideAutocomplete"', // disable file conversion
|
||||||
|
replacement: {
|
||||||
|
match: /if\(\i.length>\i\)/,
|
||||||
|
replace: "if(false)",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
|
@ -1058,6 +1058,10 @@ export const EquicordDevs = Object.freeze({
|
||||||
name: "Buzzy",
|
name: "Buzzy",
|
||||||
id: 1273353654644117585n
|
id: 1273353654644117585n
|
||||||
},
|
},
|
||||||
|
Reycko: {
|
||||||
|
name: "Reycko",
|
||||||
|
id: 1123725368004726794n,
|
||||||
|
}
|
||||||
} satisfies Record<string, Dev>);
|
} satisfies Record<string, Dev>);
|
||||||
|
|
||||||
// iife so #__PURE__ works correctly
|
// iife so #__PURE__ works correctly
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue