#๐งฉ-plugin-development
1 messages ยท Page 62 of 1
brain rot lmao
send it i dare you
u go girl
shit was like a scavenger hunt
the only problem now is that it also highlights in other messages
@someone
and thats not good ...
horror what the hell
how do i use an object as a settings store value
its not saving
by any chance, does the object contain unserializable object?
that could be the problem
no its an empty object
on second thought
its a proxy of the previous store state
wait, what are you trying to do
i think i wanted to do the same thing earlier but gave up
i fixed it
just copied the properties manually
https://github.com/Vendicated/Vencord/pull/2616/commits/09182add065f5f6ace1b2362a8d18f9bb073fbca#diff-a920d1a1610cd6128d281fb23b56be7af2a860c135004db900edac7c7f197889R154-L164
can I understand how MarkdownRules is undefined but in console is not nor in Api
why do I feel evil 
||ignore Devs.Ven||
I am so confused??? what's that suppose to say
MarkDownRules instead of MarkdownRules
OH
I guessed that was because your plugin is called MarkDownRules but ยฏ_(ใ)_/ยฏ
I hate myself
no
Markdown is just 1 word :3 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
not Mark Down
snake case wouldn't have changed anything
you would have just typed mark_down_rules
and exploded


Why he squished
finally done with the markdown api
that's isn't ideal, is it? I don't want it to complain about the Rules function returning missing attrs so made two different interfaces
MarkDownRules branch
I believe there is an obvious way to deal with this without as unknown
but aren't seeing it
Use Partial<MarkdownRules>
thanks
instead Rules it's better to change the name to rules cos it's a property
noted
That's really cool actually
sigh whatever dude
THAT WAS SUCH A FAST BAN LMAO
sucks to be you
was trying to make mentions possible but I keep losing my sanity debugging the crash

When you'll release it i'll try to make it
Oh wait you already have
Oops
you can try because I already did and I will try again after a year
Got it set up now but i have like no idea how to work the api, even after reading the source code- some sort of example plugin would be v cool
lemme. here, check module 428595, and debug
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { MarkDownRules, PluginMarkDownRules } from "@api/MarkDownRules";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
export default definePlugin({
name: "Rules",
description: "Test Markdown Rules",
authors: [Devs.iamme],
dependencies: ["MarkDownRulesAPI"],
start() {
},
rules(rules: MarkDownRules) {
return {
PROFILE_BIO_RULES: {
codeBlock: rules.RULES.codeBlock
}
} as PluginMarkDownRules;
}
});
rules.Rules has all the rules I think, it has the mention rule
I still don't understand rules completely, but I learnt how they work kinda
here js snippet that was satting for months in my inputbox #๐-js-snippets
function extractCodeBlocks(messageId, channelId) {
let index = 0;
const message = Vencord.Webpack.Common.MessageStore.getMessage(channelId, messageId).content; // replace them with the actual ids
const parser = Vencord.Webpack.wreq('428595').default.RULES.codeBlock;
while (index < message.length) {
const char = message[index];
if (parser.requiredFirstCharacters.includes(char)) {
const l = message.slice(index);
const matched = parser.match(l);
if (matched) {
console.log(matched[0]);
index = index + (matched[0].length);
}
}
index++;
}
}```
it prints every codeblock found in the inputted message
it emulates how the actual discord parser works
yk, maybe emulating the mention is better by mimicking the style
whatd i miss ๐ฅบ
I haven't made a rule yet but i assume you can just pass the user object to the actual mention component?
I believe so, its the user object or the id
it been a while
saying my experience may mislead because the unknown nature of the crashing
ofc it works, I made it
idk what the context of this is, but does it work in notes?
oh wow, when summaries was so accurate?
So fucking real
I don't think so, notes don't have any markdown rules
you could patch the component tho and force it to use the rules 
There is probably 20 million different ways i fucked that pr up but it's there if you want it 
Alright you're on your own
goddamnit
I also have no fucking clue how to do the mention thing
Turns out it isn't as simple as shoving the mention rule in the bio
๐ ๐ ๐ ๐
I thought the same, I wouldn't has asked you if I have done it
but sure thank you for your attempt
My incredibly feeble attempt
I feel like it wouldn't be hard to write a custom rule instead of trying to grab the pre existing one
Not efficient when one already exists but if it's not gonna work, might as well try
that's how may be possible yeah
hey question for you 2 nerds (or anyone else but youre active rn and every time ive asked i havent gotten an answer so idek if its possible but im hoping it is anyways imma shut up and ask my question now);
Is there a way to, and if so how do i, grab and render a react component from base discord? if that makes sense.
There's a bunch of plugins that do that
Use findComponentByCodeLazy
You pass a list of code the component contains until you have a specifier good enough that it only matches that component
any specific example?
Ummm yeah holdo n
I couldn't think of one so here's a line from one of my unreleased plugins
const UserPopoutComponent = findComponentByCodeLazy("customStatusActivity:", "isApplicationStreaming:", "disableUserProfileLink:");
Essentially, the user popout component is the only component that contains all 3 of those code snippets, so that's what the function returns
You can look at the component definition for parameters (and make an interface for it if it matters)
userpopout being this thing?
i ask because this is what i need, so if i can just yoink code i might as well 
Yop
Yeah feel free to steal it idm
There is probably a way better find for it tho

how to break discord 101
How the actual fuck
Doesn't beat this thing i did some time
* {
display: flex;
}
yeah no chance 
works pretty good as well
I fear
Well that was an experience
uh how would I find that part of the javascript is controlling this array of roles in the profile
I found onOpenProfile but there are like 50 finds
(onOpenProfile is triggered when clicking the +4)
react devtools
yeah it was hard
I unsucked the new profiles
took me way too long ๐ญ
should I create a pr for that to create as a new plugin? since others' probably would want that too, not sure
just ineligible yourself from the experiment
I like the new profiles tbh
I just hate the simplified roles and bio
(which I both did fix)
ye
id only minimize the roles if theres an obnoxious amount of them
if thye only have like 10 roles whytf would i go full profile
yeah true
So i'm patching the getUserProfile function so i can modify the non nitro user profile theme to an averaged pfp color, to make it less ugly. Problem is, i need the avatar data to process it so the function needs to be async.
TLDR: What's the best way to go about patching in async processes in an already existing non async function (if it's even possible
)
thanks google
patches: [
{
find: "UserProfileStore",
replacement: {
match: /(?<=getUserProfile\(\i\){return )(\i\[\i\])/,
replace: "useAwaiter(async () => {await $self.colorDecodeHook($1)})"
}
},
],
async colorDecodeHook(user: UserProfile) {
if (user) {
if (user.themeColors) return user;
let palette = await Vibrant.from(user.getAvatarURL()).getPalette();
if(!palette.LightVibrant?.hex || !palette?.DarkVibrant?.hex) return user;
let newUser = user;
newUser.themeColors = [Number.parseInt(palette.LightVibrant?.hex), Number.parseInt(palette.DarkVibrant?.hex)];
return newUser;
}
return user;
},
there is also a huge chance i fucked up the color format
BAD
THANK YOU EINSTEIN
- useAwaiter(async () => {await $self.colorDecodeHook($1)})
+ $self.colorDecodeHook($1)
- async colorDecodeHook(user: UserProfile) {
+ colorDecodeHook: (user: UserProfile) => useAwaiter(async () => {
does this work?
It doesn't, but it's also just as likely to be a stupid mistake of mine
discord uses this package for markdown btw https://www.npmjs.com/package/simple-markdown/v/0.7.2
so you don't have to make your own types
I don't think plug-ins are allowed to add dependencies
its an addition to the plugin api
not an individual plugin
send the plugin
I think discord already fully rewrite it cos last upd of package is 3y?
https://github.com/ItzDerock/discord-markdown-parser or https://github.com/merlinfuchs/embed-generator/blob/main/embedg-app/src/discord/markdown.js
be better I think
no
they use either version 0.7.1 or 0.7.2 of simple-markdown
but the only change in 0.7.2 is the removal of @types/node as a dependency
so you might as well use 0.7.2
just tested heading regex and it doesn't work as in discord
so they use their own version or even one from scratch
tbh even in discord-markdown-parser heading doesn't work correctly under some conditions
The following software may be included in this product: simple-markdown. A copy of the source code may be downloaded from https://github.com/Khan/simple-markdown.git.
yea, I saw it
i have compared the minified code
probably they just put it there as source of their fork
they use simple-markdown 0.7.1 or 0.7.2
they use a lot of old dependencies with no modification
mb it's old file that they didn't delete
no
but then heading shouldn't work
at least*
are you saying they use one of these?
they defenitely do not
nope
but they works
oh that would make it much easier to deal with markdown and understand it, this looks like exactly the use case in the module code without the non sense ofc
Im not sure if this is the chanel for this question, but how do i change the dm icon with CSS?
like the avatar? + you may want to check the bios of the channels before asking
would it be too "suspicious" if I patch the sendMessage function and change the flags? for example attaching SuppressEmbeds which you normally wouldnt be able to
okay so ive been doing some research
im going to pr the showhiddenchannels plugin to listen to events which would indicate that the state of a guilds channels has been updated, and then resolve those updated channels. idk if that makes sense or not
trying to fix a bug where, when you first join a server that gives you a role upon joining that gives you access to those channels, the channels are automatically unhidden
sorta asking here if its worth doing or not for my first (proper) pr
doesn't sound worth it as those channels were meant to be locked and upon opening it would try to fetch messages which will result in flagging the account
doesn't sound very useful either
i suck at communicating this but
join server with hidden channels
given role that gives you access to those channels
instead of pressing ctrl + r, my code will subscribe to the channel opened event (i think thats the right name?) and resolve all the opened channels
show channels as open when they should be
lemme guess you going to make a feature for hiddenChannel to sub to channels before closing and than racv as much message as possible?
or you saying if you sub to those channels before they get closed you will be able to listen to messages?
I dont understand what you want
what Nuckyz saying is what you planning isn't clear enough @floral tapir. is my guess correct?
oh I get it
you want to get a list of channels which you got access when you got a role (and obviously do something with it instantly)
hmm I don't know if there is an easy way for that
sorry i was murdering a bunch of small ants
so when a user gains access to a channel they did not previously have access to, the plugin will reflect that
as of right now, when a user gains access to a channel, it still shows as "hidden" @iron epoch @cedar olive
if that makes le sense
oh
do i use the flux dispatcher interface to listen to events?
is it in a component?
its @webpack/common
no
this
this
if a user gets a role that gets access to the log channel, it should turn into a normal channel
but it does not
the channel still displays as being hidden
does it fix when you switch servers?
its a very easy fix tho
doesn't matter, it's a thing that rarely happens
listen to the channel opened event, and then pass all those channels to the resolver
and that can be fixed when the plugin is rewritten
bruh
easier said than done
i just wanna start contributing to vencord pls lemme do dis 
so i can get my feet wet
lol
ive got zero experience working with this codebase but i wanna start contributing
there are easier things to do than this
such as
look at plugin requests if you want an idea for a plugin
or here for a fix to do https://github.com/Vendicated/Vencord/issues
also the actual fix for that issue will need deep debugging to see why it's not working in the first place
it should already be working, the functionality does need to be added
the issue i was talking about?
yep
which I'm sorry to say if you are starting this is may be too hard
create a voice channel which is locked, then give you a role that gives you permission to connect it
educate me sir
you are gonna see the icon change and the voice channel be accessible now
which means the listener is there and it should be working for hidden channels too
the listener is not something vencord adds, it's something discord already has for the channels
shit ur right
also the actual fix for that issue will need deep debugging to see why it's not working in the first place
it should already be working, the functionality does need to be added
so this applies
mm maybe i went too much ๐ค โ๏ธmode
choose something more simple from the issues in the repo
how do i test to make sure my code works? as in, is there any resources that can show me how to set up a dev environment
i have my code ready but i wanna test it first
tyily
all the easy fixes are literally one line fixes
do i add myself to the devs for super minor changes
lol
only for major changes you can
I am having problems trying to inject compiled vencord with my plugin, according to cli it was patched but when I open discord it is default
but when I open Discord it is unpatched
Am I allowed to ask questions regarding the development of plugin in this channel?
Basically, m tryna understand how to get started. Like the general process of getting started with plugin development
gotcha
thanks a lot.
in the process, i have to inspect the js code right? of the discord
enable react devtools in settings and use it to go to functions
ok tnx
thanks a lot
any idea? ๐
rip
Open the console, check if there are any errors with your plugin
I had the same issue when I wrote broken regex which prevented vencord of loading
fixed, thank u โค๏ธ
I am trying to use a photo in the rich presence but it does not work, what can it be?
arent those assets that are on the application?
only the small_image
I can't use image links there?
not afaik
look at customRpc
daam, I forgot to put it in the large as well, I had it only in the small.
im so stupid XDDDD
its working now
thank u
I have finished the plugin, how can I make a request for it to be added? should I make a pull request?
yea, pr
please guys add a plugin that see hidden channel just see text but cannot send
i will give money forthat
physically impossible โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
whyyyyyyyyyyy
money first 
name checks out
tru โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
hii quick question
for https://github.com/Vendicated/Vencord/tree/main/src/plugins/gifPaste
with the string "handleSelectGIF"
where does that come from
The cutest Discord client mod. Contribute to Vendicated/Vencord development by creating an account on GitHub.
discord functioon
mwah im going to make out with you rargh
currently trying to find which function is called when you click on a gif while running a command so i can pr gifpaste
what the fuck
cry stinky loser
@floral tapir Are you rasputin
geek activities
I like idea rasputin is still alive and the one thing he decides to do is write code for Vendor
Real
But I was talking about their pronouns
It said "Russian's greatest love machine"
ryan gosling burp gif
Understandable
I hope this doesn't sound like smth political but ััััะบะธะต ะฒะฟะตััะด 
why is this not pinned yet
where'd the docs in the vencord repo go?
did they move somewhere else
nevermind, found them
please turn on your brain
mission impossible โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
discord doesnt send any of the info needed
Patience ๐ญ
Is there a way to use react devtools while breakpoint paused? i might be stupid but the element eyedropper thing just doesn't display or pick anything
ikik
can someone make a custom ringtone plugin of the Halloween call sound or the xmas one they where good
wrong channel #plugin-requests
don't think so
react devtools eyedropper is so cursed anyway
hey, sorry this might be a dumb question, but im trying but idk how to get the function i want
basically, the plugin that i am trying to make will , once the user types a msg and hits enter to send it, the plugin will get the text and replace some texts within the user input before sending it. it ill work as the user is typing it. but idk how to get the function thats related to this
itll be generous if someone helps . tnx
there's the text replace plugin for that
what can i do with it if u dont mind me asking
I don't use it myself so I couldn't tell you, but if you want a simple plugin to replace text in messages when they get sent, use text replace
you did mention replacing text in the message bar before it was sent, I'm not sure the use case tbh?
well bascially i want to replace texts with icons
so if user does something like
this is a {{cat}} my plugin will replace it witha cat emoji
this is a ๐ฑ
that moment when :cat:
ya but this is limited to just the emojis
i would like to use other icons as well that u cant find in emojis
the plugin u gave, like can i define my own text replacement?
k lmme check
import {
addPreEditListener,
addPreSendListener,
removePreEditListener,
removePreSendListener
} from "@api/MessageEvents";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
export default definePlugin({
name: "idk",
description: 'idk',
devs: [],
start() {
this.presend = addPreSendListener((_, msg)=> {})
}
stop() {
removePreSendListener(this.presend)
}
})
@hidden obsidian
but yeah, if you can it might be better to justr use TextReplace
but if you dont need to make a whole other plugin, why do it?
uu.. thanksh. im looking at textReplace. lemme check if itll work for me
๐ญ
i sent that before your message rendered :p
yep, that'll do it for me. thank you
np
m happy and sad at the same time after finding it ๐ ๐
dw, I spent way too much time trying to do something CSS can do in 1 line haha
that time wouldn't have gone to anything useful anyway
lol
unrelated but
- why are you making a plugin repo (defeats the whole purpose of vencord)
- why are you downloading the entire repo locally instead of downloading each plugin individually when the user installs them
so i tried to make a plugin to make the view full bio button expand in the same popup as the profile
and after like 30 mins of trying stuff i present to you the worst patch that has probably ever been made
{
find: ".viewFullBio,",
replacement: {
match: /(\[(\i),\i\]=\i\.)useState\(!1\);(.{0,100}ref:(\i))=>{null!=\i(.{0,500})className:(\i.descriptionClamp)(.{0,300})onClick:\(\)=>{.{0,300}}\)}/,
replace: "$1 useState(null); const [clamp,setClamp] = Vencord.Webpack.Common.React.useState(true);" +
"$3 => { $4 != null && $2 == null" +
"$5 className:clamp ? $6 : null" +
"$7 onClick: () => setClamp(!clamp)"
}
}
(broke the next day its joever)

I also made my 2nd plugin I just copy and paste from other plugins till it worked the way I wanted it too lol
its cancer the code
but it works
supports twitter/tiktok as well
feels cool
- I think you've asked before, but to make it easier for advanced users to find and install third party plugins. There's no plausible way a plugin repo would work on base Vencord either way. Its meant to only be used with dev Vencord as a third party plugin
- The repo itself doesn't have the plugins stored in it. All the plugins are downloaded from their respective githubs elsewhere in the code. This code just makes sure the plugin repo's code is up-to-date and automatically updates it so the user doesn't have to manually update it
ok makes sense
hello, quick question doing waitFor subscribe and dispatch to get the fluxdispatcher for some reason returns me something else that's not the dispatcher, temp1
cuz my plugin starts on domcontentloaded and i need to wait for webpack stuff to load before using it
last time i asked there wasn't a way to start it after webpack but before login
dunno if that's still the case
why do you need that?
because if the user isn't logged in, the plugin will never load, but i want to send an event when discord is loaded (eg on login screen)
regardless of logged in status
i took the snippet from webpack/common/utils.ts, been using it for months with no problems
now it stopped working smh
i guess adding register in the parameter list further narrows it down and it brings me the correct thing, dunno if it's the ideal solution tho
@viral roost you need to stop with these dangerous patches
you cannot define a variable in one patch and use it in another
that's very dangerous because if the first patch fails but the second one still works you are guaranteed to cause a crash
try to avoid it, or if there's no way around it mark your patches as group: true
How does grouping work?
If any of the patches failed, they all got reverted or working patches ( before failed one ) stays there, but any next patches are not applied?
yes
revert
i honestly didn't see the try catch somehow
but yes group
#๐พ-core-development message
@iron epoch
It will work in implementation that you have sent, but it will not work in discord default one
Discord takes the whole string, matches a rule with smallest order and removes match from a parade string to pass what has left to other rules
So if a string doesn't start with a needed character it will pass it to the text rule, which will eat your cookies
Also multiple characters like this works fine
src/plugins/messageColors/index.tsx: Line 67
requiredFirstCharacters: ["hsl", "rgb", "#"],
that's not my implementation though, its directly from the discord code
can you point where discord takes the whole string?
o.prevCapture?""
Search for it, I can't make a screenshot since I'm not home
var c = function(t, o) {
var s = [];
for (n = o = o || n; t; ) {
for (var u = null, l = null, d = null, f = -1e5, p = 1e5, h = [i.get(t.charCodeAt(0)), a], m = 0; m < h.length; m++) {
var g = h[m];
if (null != g)
for (var _ = 0; _ < g.length; _++) {
var b = g[_]
, v = e[b]
, y = v.order;
if (y > p)
break;
var E = null == o.prevCapture ? "" : o.prevCapture[0]
, S = v.match(t, o, E);
if (S) {
var x = v.quality ? v.quality(S, o, E) : 0;
(y < p || x > f) && (u = b,
l = v,
d = S,
f = x,
p = y)
}
}
}
if (null == l || null == d)
throw Error("Could not find a matching rule for the below content. The rule with highest `order` should always match content provided to it. Check the definition of `match` for '" + r[r.length - 1] + "'. It seems to not match the following source:\n" + t);
if (d.index)
throw Error("`match` must return a capture starting at index 0 (the current parse index). Did you forget a ^ at the start of the RegExp?");
var w = l.parse(d, c, o);
Array.isArray(w) ? Array.prototype.push.apply(s, w) : (null == w.type && (w.type = u),
s.push(w)),
o.prevCapture = d,
t = t.substring(o.prevCapture[0].length)
}
return s
}
That's how discord parses it despite having my custom rule
And that's how it works if I change text-rule-regex to stop right before hsl( or rgb(
It rgb definetly doesn't starts with rgb, so it parsed like a normal text... which takes important part
pinged wrong person oops
@iron epoch
That's default text regex that discord uses
the regex for the text rule?
yes
fair point than
I will experiment with reactParserFor, to see if i am able to create a set of rules
note for note hook: wreq(702557).Z
?remindme 12h continue notes plugin notable stuff wreq(252032).Z wreq(252032).Z
Alright @flint bronze, in 12 hours: continue notes plugin notable stuff wreq(252032).Z wreq(252032).Z
724593
?reminder list
continue notes plugin notable stuff wreq(252032).Z wreq(252032).Z
?reminder delete 1452282
Successfully deleted reminder.
i hate lazy loaded classes
D3SOX Plugins broken? ๐ฅฒ its been like this for a bit now
yea
as temp solution u can move all plugins (all folders but d3soxUpdater, shared and native) from D3SOX-userplugins into just userplugins
it will remove feature to auto update of his plugins but it works (as temp "updater" u can just check his github for fix)
Is there a designated function to check if anyone in your dms is typing? I'm trying to make a plugin that changes the home button icon to a typing indicator if someone is typing, i started it a few weeks ago but gave up- right now it has this absolute monstrosity of a function and i doubt it even works
//pain
let isTyping = findByCodeLazy("isTyping(", "getTypingUsers(");
let getTypingUsers = findByCodeLazy("isTyping(", "getTypingUsers(");
IsAnyoneTyping()
{
let channels = PrivateChannelSortStore.getPrivateChannelIds();
return channels.some(channel =>
{
if(ChannelStore.getChannel(channel)?.isMultiUserDM())
{
return getTypingUsers(channel).some(e => e.id !== UserStore.getCurrentUser().id);
}
else
{
if(isTyping(channel, ChannelStore.getChannel(channel).getRecipientId()))
{
return true;
}
}
})
},
Not that I'm aware of
It's joever
I see, thanks!
I got it to work!
const ThreeDots = findExportedComponentLazy("Dots", "AnimatedDots");
const TypingStore = findStoreLazy("TypingStore");
const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
export default definePlugin({
name: "HomeTyping",
description: "Changes the home button to a typing indicator if someone in your dms is typing",
authors: [Devs.Samwich],
TypingIcon: () =>
{
return (
<ThreeDots dotRadius={3} themed={true} />
)
},
IsAnyoneTyping()
{
let channels = PrivateChannelSortStore.getPrivateChannelIds();
return channels.some(id => Object.keys(TypingStore.getTypingUsers(id)).length);
},
patches: [
{
//insanely cursed find
find: "M19.73 4.87a18.2 18.2 0 0 0-4.6-1.44c-.21.4-.4.8-.58",
replacement: {
match: /let{size:\i="md",width:\i,/,
replace: "if($self.IsAnyoneTyping()) return $self.TypingIcon(); $&"
}
}
]
});
Only thing is, the home button icon doesn't change until you hover over it, is there a way i can update it as soon as someone starts typing?
I assume it's some react insanity
useForceUpdater and setInterval to check every few seconds
and if its true call the forceUpdater
or just forceupdater every few seconds, either will work
Yeah i was gonna say
Would calling force updater like that have any performance problems?
i think no? since its only rerendering the tiny dms icon
Ah ok
ideally u would useStateFromStores to get live updates
yes
but idk how to do that with all dms
use that
I think i am having a stroke
return useStateFromStores([TypingStore], () => channels.some(id => Object.keys(TypingStore.getTypingUsers(id)).length > 0));
?
yeah that works
doesnt work with the in app icon feature @balmy sky
you are literally patching entirety of ClydeIcon btw
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findExportedComponentLazy, findStoreLazy } from "@webpack";
import { useStateFromStores } from "@webpack/common";
const ThreeDots = findExportedComponentLazy("Dots", "AnimatedDots");
const TypingStore = findStoreLazy("TypingStore");
const PrivateChannelSortStore = findStoreLazy("PrivateChannelSortStore") as { getPrivateChannelIds: () => string[]; };
export default definePlugin({
name: "HomeTyping",
description: "Changes the home button to a typing indicator if someone in your dms is typing",
enabledByDefault: true,
authors: [Devs.Samwich],
TypingIcon: () => {
return (
<ThreeDots dotRadius={3} themed={true} />
);
},
IsAnyoneTyping() {
const channels = PrivateChannelSortStore.getPrivateChannelIds();
return useStateFromStores([TypingStore], () => channels.some(id => Object.keys(TypingStore.getTypingUsers(id)).length > 0));
},
patches: [
{
// insanely cursed find
find: "M19.73 4.87a18.2 18.2 0 0 0-4.6-1.44c-.21.4-.4.8-.58",
replacement: {
match: /let{size:\i="md",width:\i,/,
replace: "if($self.IsAnyoneTyping()) return $self.TypingIcon(); $&"
}
}
]
});
here is what I have right now
Yeah mine is pretty much indentical
It works for me tho
Guess all i need now is to move the patch
yeah pretty much
ะ ะพััะธะธ ัะปะฐะฒะฐ
probably u can use FluxDispatcher.subscribe("TYPING_START", ...) to catch it
look at how typing indicator does it
which is useStateFromStores
yep
my solution should work good enough for this simple use case then
what's your solution
this
oh yeah it's right
Yeah it works well enough 
How can I findbyCode this:
api = Object.values(wpRequire.c).find(x => x?.exports?.tn?.get).exports.tn;
uhhh did i miss something
what's the error..?
well i thought it was weird that it didnt recognize the modules
nope
and yes
i have it opened as a folder
make sure you follow https://docs.vencord.dev/installing/editor-setup/ btw
and what's the error?
yeah i've done that already, just that i had to install the extensions manually since they didnt pop up in my recommendeds tab
what's the error when building?
oh nevermind i guess i just had to restart my pc, now it works fine
thanks and sorry for bothering
Give more context
probably u open ur plugin's folder. u have to open a whole vencord folder or just single file
let wpRequire;
window.webpackChunkdiscord_app.push([[ Math.random() ], {}, (req) => { wpRequire = req; }]);
let ApplicationStreamingStore, RunningGameStore, QuestsStore, ExperimentStore, FluxDispatcher, api
ApplicationStreamingStore = Object.values(wpRequire.c).find(x => x?.exports?.Z?.getStreamerActiveStreamMetadata).exports.Z;
RunningGameStore = Object.values(wpRequire.c).find(x => x?.exports?.ZP?.getRunningGames).exports.ZP;
QuestsStore = Object.values(wpRequire.c).find(x => x?.exports?.Z?.getQuest).exports.Z;
ExperimentStore = Object.values(wpRequire.c).find(x => x?.exports?.Z?.getGuildExperiments).exports.Z;
FluxDispatcher = Object.values(wpRequire.c).find(x => x?.exports?.Z?.flushWaitQueue).exports.Z;
api = Object.values(wpRequire.c).find(x => x?.exports?.tn?.get).exports.tn;
This works fine in the console. Trying to convert it to a plugin and get "api" using findByCode
Somehow you gave more context and i am even more confused
Vencord.Webpack.Common.RestAPI
no need to find what's already a common
How about fetch? Does fetch works too?
what?
for sending requests? technically yes, but Discord might unleash the wrath of antispam upon you
RestAPI sends all the correct headers
so best to use that
it's already in vencord webpack commons so you can just import it
Okay thanks
or are you not using Vencord?
password protect channels
:D
navigating to channels/@me is necesary for it to refresh the nsfw popup, just need to make it refresh on unlock and change some strings
@dull magnet can u put gifs in plugin readmes
i wanna put the above
but also a screenshot of the lock screen is probably enough?
oki
why simplified profile experiment is not showing up?
v+ needy @tough ridge
does this error mean anything
im getting it randomly, but my plugin still works
odds are i am doing something very wrong
you are trying to set the value ofa setting to something like a class or proxy or function
can settings be objects?
ok, thanks
if you need help put a breakpoint and inspect everything you are trying to save
its 3 am for me, that will be an issue for future me
lol
?remind 7hr fix plugin
Alright @hushed loom, in 7 hours: fix plugin
hello, is there any start-up guide on how to start developing plugins?
thank you
every day we are closer to me having the motivation to make the annoying vencord popup plugin
it will have 0 use and just be a nuisance
font-family: "Builder";
font-code: "Builder Mono";
--font-family: 'Builder ;
src: url('https://files.catbox.moe/8u8dak.woff2') format('truetype');
}
body
{
font-family: 'Builder Sans' !important;
--font-display: "Builder Sans";
--font-headline: "Builder Sans";
--font-code: "Builder Mono Regular";
src: url("https://raw.githubusercontent.com/ardishco-the-great/catpuccin-with-emojis/main/Terminess%20(TTF)%20Nerd%20Font%20Complete.ttf");
}
[data-list-item-id^=channels___] {
font-family: "Builder Sans", var(--font-primary);
}
@import url('https://raw.githubusercontent.com/ardishco-the-great/catpuccin-with-emojis/main/Terminess%20(TTF)%20Nerd%20Font%20Complete.ttf');
:root {
--font-primary: "Builder Sans";```
@hushed loom, <t:1719645225:R>: fix plugin
@balmy sky
https://github.com/Vendicated/Vencord/blob/main/CONTRIBUTING.md
It's asked to create a plugin request beforehand, so they have read this first
Ah makes sense
Hey, anybody got a patch for channel hover?
Hello, i'm new to plugin development, how do I find patches?
react devtools are a good place to start
what do i do from there? after i'm in react devtools, and i am in componets, what do I do next?
this button will take you to the discord source for the component
use that to make patches
ahhhh okay!
yea read that already
thanks for the info!

does the find field find the point of code your at and the the match field does whats after that?
discord splits its code into numbered modules
the find part will find the module
the match part is regex that will match code only in the module found by the find
and replace it with the replace part
Look at discord code
Find a thing that you would like to change
Find a unique string from this module, that you gonna change, no any other modules should have this string - it's gonna be your find
match is just a regex that tells which exact part you want to change from this module
okay! am I allowed to take patches from other plugins in they have what I need for my plugin to work?
yes, but be careful not to collide with other plugins
Using the same find shouldn't be the problem, but you should be more aware of match/replace to not cause conflicts
mods, lobotomize this person
๐ง ๐จ
okay thanks!
defaultValue prop?
i dont know how i missed that, tysm
Would a plugin that adds support for loading chrome extensions be a terrible idea
I feel like it could have some random uses
vencord already has an api for it
used for loading react devtools
it can download and load extensions from chrome webstore
it just has no way to use it
*electron
no
vencord
yeah i'm looking at that]
installExt("fmkadmapgofadopljbjfkapdkoienihi")
it's a wrapper though
probably useless in this case though
for the reason you are already familiar with
cough cough chrome web store review
Is it possible to interact with datastore in a native.ts function? i'm trying to use native to fetch the data of an image (not relevant), but as soon as i add the DataStore.get("cachegifs-cache") line vesktop just loads indefinitely
Wtf are you trying to build
Sounds redundant
This is your issue
Caches the base64 data of favourite gifs so it doesn't take 80 million years to load each time
yeah that isnt your issue
they're all CDN links
through the media proxy
probably regenerated every load though
OH GOD SHIT MAYBE I DIDN'T THINK THIS THROUGH
Maybe the world aint ready for this tech yet
Normally I would say "STOP FUCKING USING DATASTORE; SETTINGS IS FINE FOR MOST THINGS" but settings is not for this
Settings would be fineee
It works well from what i can tell tho
Downloading the data has frozen my client on 9 seperate occasions now tho
Oh god what r you cooking Sam
I'm cooking ok just trust
ok asking for a friend
Um
Is it bad if opening my vencord settings backup takes up 5gb of ram
THE DATASTORE DATA WAS SO BIG IT BROKE THE BACKUP SYSTEM
LIKE I COULDN'T IMPORT OR EXPORT ANYTHING
๐ญ
This is so cursed
Someone please take their computer away
The motherload
@balmy sky I'm begging you to just store these files in a folder like a normal person
I might try to make an in client integration of the developer dashboard
one day samโs account is going to get termed for the stuff they do and we canโt be surprised when that happens
OBVIOUSLY
i didnโt mean termed for client modding i mean being termed for the code you write
The latter is more likely
why?
my brain going to explode
@chrome folio hi there. I would like to inform you that your "ShowAllRoles" plugin makes the profile unscrollable with a huge amount of roles.
@viral roost hi there. I would like to request a feature for your plugin "MaskedLinkPaste". if possible, could you make an option for it so when pasting it automatically adds <> to block previews?
example + (CTRL+V) -> [example](<https://eff.org/>)
this is a 5 minute job honestly
what is this regex
Hi there.
You should see the regex for my unit converter plugin, it's a horror show
Are there docs on how to use the api (Vencord.Api.*)?
Hi bro
Read the source code
Damn
Specifically src/api/index.ts
It has comments
Can i fork and add a page to docs for that
Idk if im just sped but i think thatd be easier like readthedocs type thing
Honestly documenting the code with comments as it is is probably easier to develop upon
lua โ Today at 3:04 AM
That being said can you send a pull request from another git instance I reaaaally dont want to use github
Cause i wanna contribute to the docs but theres not a mirror on codeberg
you could ask in #๐-doccer probably
so functions dont have to be called like function myFunct(){}?
it can just be myFunct(){} in typescript?
if you're struggling with such simple language features you should learn better js first
Was just a question damn
Im legit just asking for understanding because i know js i *dont know ts * :ass:
it has nothing to do with typescript
??
Writing ts is the same as writing js, but with optional typing, thus better lsp support
Okay hold on
Okay i was retarded for a little bit ๐ค
That should be good
I think i can ignore this (question mark)
this isn't a good idea, manipulating the dom directly is not recommended
wait, are you putting an image on top of the page?
Ya
export default definePlugin({
name: "brainrotGallery",
description: "randomly displays funny pictures",
authors: [Devs.zav],
});
oh I see, yup this is meme month
its a recurring function though
im referring to the myFunction call
put myFunction into the start function
like
start() {
console.log("its time...");
generate();
setTimeout(start, Number(`${Math.floor(Math.random() * (15 - 5 + 1)) + 5}`) * 60 * 1000 * 60 * 1000);
},
or
start () {
function myFunction() {
console.log("its time...");
generate();
setTimeout(myFunction, Number(`${Math.floor(Math.random() * (15 - 5 + 1)) + 5}`) * 60 * 1000 * 60 * 1000);
}
}
?
first one
got it
1 error
1 error
Build failed
Build failed with 1 error:
src/plugins/brainrotGallery/index.ts:60:8: ERROR: Expected ";" but found "{"
โELIFECYCLEโ Command failed with exit code 1.
damn it
hold on
ok ya im drawing a blank here
start() {
console.log("its time...");
generate();
setTimeout(start, Number(`${Math.floor(Math.random() * (15 - 5 + 1)) + 5}`) * 60 * 1000 * 60 * 1000);
};
the start function in your plugin definition
thanks
ok good news; console.log is working ๐
now we wait
okay its. not doing anything lol
it's just saying "Cannot find name 'start'"
is this also ignorable
all of your questions so far have been due to a lack of understanding of Javascript
please take some time to improve your javascript knowledge first
I fully understand javascript i dont fully understand javascript plugin development
But i am still improving
your questions so far have been:
- not knowing what a method is in js
- should i put my code inside a function that's never called?
- how do i fix this obvious syntax error
- not understanding that you can only reference object methods via an object reference
sorry but you in no shape or form "fully understand javascript" lmao
there's nothing wrong with that but these questions don't really belong here, you should improve your javascript skills first
Oh wait i see it
Dude why couldnt you have just said that
because its obv
cos this channel isn't ts/js school
I wasnt asking like it was i was just asking because i wanted to know
Its over now
It works
Im committing it
I'm attempting to set things up to create a userplugin, and would like to propose some improvements on the Vencord Docs:
- https://docs.vencord.dev/installing/custom-plugins/#building-vencord - I created a src/userplugins/foo/index.tsx where the index.tsx is an empty file and still got the TypeError mentioned here. Probably a good idea to be more exact about the conditions that lead to this error, and to point out that this error is expected until you actually have the boilerplate code set up.
- The Plugin Submission page is empty
- The docs are clearly incomplete as only the first two bullet points in the Introduction are covered.
what does already exist is very nice tho
The docs are clearly incomplete as only the first two bullet points in the Introduction are covered.
clearly.
would like to propose some improvements on the Vencord Docs:
https://github.com/Vencord/Docs/pulls
also @steel field you can continue in#๐-doccer
Question there was a prop called encodeStreamKey it was removed when all of the patches and stuff broke. without using the encodeStreamKey it seems to work fine but I wonder if it's fine to leave it like that.
The docs are like 1 week old
check this conv #๐งฉ-plugin-development message
I see alr thanks
i see lol
oh I see that the topic was cut off, I think it continues here #๐งฉ-plugin-development message
Saw that thank you!
np
since the docs are incomplete, what resources do yall recommend for me to figure out "How to reverse engineer and understand Discord code to find which functions you need to use or patch"?
ah nice, older docs, tyty
also looks very promising
yea this is probably the one that should be recommended to everyone while the official docs are a work in progress, tyty
Hello, im new to plugin development and i was wondering how to show that a modal is loading after submitted. Like once you click the button to submit the modal, i want it to show a loading icon
@chrome folio found an oversight with ShowAllRoles, specifically with roles lists that are... long https://the.yog.zone/2CDGuwd.png
using this as a (temporary) workaround: ```css
/* Add a scroller for long role lists when using ShowAllRoles */
[class^="userPopoutInner_"] [aria-label="Roles"] {
max-height: 58vh;
overflow-y: scroll;
scrollbar-width: thin;
scrollbar-color: var(--profile-body-divider-color)var(--scrollbar-thin-track);
padding-right: 4px;
&:hover {
scrollbar-color: var(--scrollbar-thin-thumb)var(--scrollbar-thin-track);
}
}
canary 306479 (cb6e309) Host 0.0.438 x64 Build Override: N/A Linux 64-bit (6.9.6-200.fc40.x86_64)
Vencord 5c05443 (Standalone)
Electron 30.1.0
Chromium 124.0.6367.243
```
how would I get a file using fs and pass it on to my main index.ts file?
i know but like how would i then pass it on to the index.ts file
look at other plugins that use native file
ok
src/plugins/openInApp/index.ts: Line 54
const Native = VencordNative.pluginHelpers.OpenInApp as PluginNative<typeof import("./native")>;
How does this work? Like I'm having the same problem, how do I input this code?
i tried that except it says the function doesn't exist.
index.ts
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Cooper/coopeeo, Vendicated and contributors*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Devs } from "@utils/constants";
import definePlugin, { Patch, PluginNative } from "@utils/types";
const Native = VencordNative.pluginHelpers.ExtraConnectionLinks as PluginNative<typeof import("./native")>;
enum contypes {
Roblox = "Roblox",
Xbox = "Xbox",
PSN = "PSN",
}
const uris = { // name = t, and id = l
[contypes.Roblox]: "https://www.roblox.com/users/${l}/profile",
[contypes.Xbox]: "https://www.xbox.com/play/user/${t}",
[contypes.PSN]: Native.resolvePSNDataUri(),
};
const serviceNames = {
[contypes.Roblox]: "Roblox",
[contypes.Xbox]: "Xbox",
[contypes.PSN]: "PlayStation Network",
};
export default definePlugin({
name: "ExtraConnectionLinks",
description: "Adds the Open Profile button to connections that don't natively have it in the regular Discord client.",
authors: [Devs.coopeeo],
patches: makePatches(),
});
function makePatches(): Omit<Patch, "plugin">[] {
const output: Omit<Patch, "plugin">[] = [];
const stringKeys = Object.keys(contypes).filter(v => isNaN(Number(v)));
stringKeys.forEach(key => {
const contype: contypes = contypes[key];
output.push({
find: "getPlatformUserUrl:e=>",
replacement: {
match: new RegExp(`(?<=${serviceNames[contype]}",.*},.+)(?=},)`),
replace: `, getPlatformUserUrl:e=>{let {name:t, id:l} = e; return \`${uris[contype]}\`;}`
}
});
});
return output;
}
native.ts
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { IpcMainInvokeEvent } from "electron";
import fs from "fs";
let psnUri: string;
function getPSNDataUri() {
return new Promise<string>((resolve, reject) => {
if (psnUri) psnUri = fs.readFileSync("./psnUri.html", { encoding: "base64url", flag: "r" });
resolve(psnUri);
});
}
export async function resolvePSNDataUri(_: IpcMainInvokeEvent) {
return getPSNDataUri();
}
"function doesn't exist" which one and where
Also I'm 100% sure that vee will say to use .map instead of pushing into output in forEach
k i will fix that
And same with patches, \i in regex for catching variables, cuz they can easily change
resolvePSNDataUri in native.ts file
No idea, i haven't worked with native
k
Wait, is it compile time or runtime error?
fully restart discord
ctrl+r doesnt reload native.ts changes
not possible
i did, unless i should take a bit longer for discord to fully shutdown.
Also, might be the issue that he's calling native functions before the plugin was even started?
runtime
Can you create a function inside of a plugin like this
function getUri(contentType) {
const uris = {...}
return uris[contentType]
}
And change patches to rerurn smth like this
return $self.getUri(contentType)
now it works... i guess i had to wait longer, but also i stopped the pnpm watch --dev command
I have a feeling that the native module just hasn't got enough time even load
well i mean the plugin don't but vencord loads now
.
it was working the way it was before.
Previously you had hardcoded strings
Now you resolve something from native part
So try it
@haughty maple so...?
sorry was doing a thing almost done with the thing you sent
it aint even starting the plugin
Why
i just found out why, it was me being the biggest idiot of all time.
I love going complicated way first
So just to check my theory
async start() {
console.log("PENIS", await Native.resolve...())
}
should be enough
If it's working here - then native module just wasn't loaded on "file-scope?", thanks to async
If it's still undefined there, idk
lets go it's now working
I'm going to sleep pretty soon, so yeah
๐
but crashes if you open up a profile that shows a playstation connection
With what reason
replace not a function prob because it's a promise
and i dont know promise very well
Show me your patch
its in my geturi function
getUri(name: string | undefined, id: string | undefined, contentType: contypes) {
console.log("[ExtraConnectionLinks]: name: " + name + ". id: " + id + ". contype: " + contentType);
return (uris[contentType] as string).replace("${l}", name as string).replace("${t}", id as string);
}
because i am stupid!
Well, native is loading, it's the most important thing
i have to put thing called .then cooper
const uri = {}
export default definePlugin({
patches,
async start() {
uri[psn] = await Native.resolve...()
}
getUri(type){ return uri[type] }
})
Horror, but you will have a string there
It's probably not gonna work
Discord expects a normal string, will get promise/undefined
imma try anyways!
also
async functions have "await" in it
instead of func().then(doSmtg)
const result = await func()
but it's more js thing
https://javascript.info/async-await ( also look at previous chapters )
i mean i know async and await, but like have not worked with writing stuff with promise
You'll get used to this
I do believe smth like this should work without big issues
And I'm going to sleep, gn
gn
btw @iron epoch
Do you know the difference between inlineStyle/inlineObject/verbaterm in md rules?
huh
They're complainign about prs again i think
Does discord already have a component for a vertical volume bar? I can't think of where one would be off the top of my head. I suppose it's possible to somehow rotate the settings slider or something similar
horror
SHUT
i doubt
how would i add a reaction to a message?
i love discord this is awesome to have
today i learned that custom pills for selects exist
shiny ? 
I think @green vessel made something that does it I cant find the original code
yes shiny
I thought exactly the same thing
I can't find it in third party plugins now
The quick husk thing
yeah
Rip
wdym
Regular gated plugin requests when
braindead?
There's like 0 actually decent ideas
if you have regular role at that point you have the brain capacity to make it yourself
it broke but i still have the code for it
They're all either impossible, uninteresting or just flat out stupid
I've made a few plugin requests before, usually because i don't have the expertise for it
Or already tried and failed
What
how react devtools doesnt have a "jump to where this component was created" button
Oh yeah that's really annoying
Also react devtools not working when paused by a breakpoint
Just makes it flat out impossible to inspect some elements
React devtools is a buggy piece of shit and I'm not afraid to admit it
Yop
Ehh it works most of the time
because it literally has to inject its own elements into the DOM to even do it
instead of native chrome devtools being able to render an overlay properly
findByCode(".userHasReactedWithEmoji")(channelId, messageId, { name: "", })
discord code is so obfuscated to tell but I was kinda able to figure out that inlineObject is basically is like an object once created you can't rewrite it and must delete it fully (examples: mentions, emojis). verbatim I have no idea, it does nothing (newline, paragraphs, text). inlineStyle is mostly responsible for rendering them with some effect, change of font or color/highlight (strong, inlineCode). and that all I know, still don't have a full picture of how they work.
(and sorry for the late reply)
So the main difference between them all is still unknown, i haven't seen any issues with any of these, it feels like they don't do anything, so that's why I asked, hoped maybe you have figured it out
does a thing exist where you can get the path where your plugin is running?
you are trying to load something from the filesystem
dont do that
look at how quickcss works
i am trying to get a file
okay
also
let me look at what you have
nvm cant because you didnt commit it
all I can say is
Whatever you are trying to do is a hack
and there are better ways of doing it
What does that psnUri.html file contain?
Mod to view content of hidden channels โผ๏ธ
if you can't implement it within the Discord client it's probably not appropriate to add
because I think I know what you're trying to do, open a fake PSN profile replica webpage
nope
what does it do then?
it's gonna do this https://github.com/Vendicated/Vencord/pull/2642#discussion_r1660219394
it was just for development after i got it done i would replace it and stuff
I'm going to be brutally honest
This is a really bad hack promoting a user-hostile service
'
k i will try to find a different service then
you can just import files
import htmlString from "file://psnUri.html"

it's supposed to open in the browser is the issue afaik
this is the ideal solution
i see an official way calle My PlayStation, but it has dissappeared from the website :(
I love sony (xbox user btw but i really wanna upgrade and switch to ps)
WHY SONY WHY
console wars is dead
no point simping over a certain console
ps5 has no games anyway
ik
true
All the people doing console wars became over 10 and swapped to pc
i'd assume there are 0 exclusives on xbox these days
I have a xbox one that runs like absoulute crap, i tried launching roblox, it didn't launch. My PC has low specs too
at this point consoles are glorified mid-range desktops with a fucked up operating system
well fuck playstation support!
except for the nintendo switch
shit is worse than a 5 year old low-end chromebook
not as bad as the chromebooks that my school gives out
trol
the switch's ui was great until they added that one god damn red ugly nintendo switch online button
doesnt that menu run like ass anyway
yea, also it's even worse if you have joy-cons that have the best joy-con feature.... STICK DRIFT
Did you discover it yourself yet?
def css-able most likely
it's called
video
Yop
yeah
But i kinda lost motivation for the idea anyway
is that its own component?
how would ya check if a user is friends with you with css?
Not sure
What did you need for it
not possible 
I was gonna make a volume manager thing
Like you can change the volume of every sound in the app
thats what i thought
i thought someone made this
I thought it was only call sounds you could change?
probably a BevilDroยฎ๏ธ plugin
I love bevildro
discord gamepidgeon
sharing game state through links that embed as images just like they do on gamepidgeon to ppl who dont have it installed
BevilDro
discord activities 
i love hacking on gamepigeon
HORROR
how
@flint bronze i chose the stupidest fucking icon possible
It's so beautiful
Standing man vs running man
I wish there was more running icons
hacking on the darts game
A simple x2 (?)
trol



