#š§©-plugin-development
1 messages Ā· Page 13 of 1
then ven will create new account and server and put it on github
since github exists backup server would be meaningless imo
still stuck on this part :(
Oh damn
finding that function will be painful
const fetchProfile = proxyLazy(() => {
const id = findModuleId("fetchProfile error:");
const signature = wreq.m[id].toString().match(/fetchProfile error:.+?(return .{1,3}\.apply\()/)[1];
return Object.values(wreq(id)).find(v => typeof v === "function" && v.toString().includes(signature));
});
works
do you use dc in Norwegian?
haha v cool :D
there also used to be a plugin that let you open arbitrary web links in dc windows
Would it be even remotely plausible to have client mods for iOS discord?
Ya
It's been done
But vencord won't touch android with a 7km stick
Even less iOS
Both are cursed as fuck
Refer to aliucord at best
huh i thought there is vencord for the discord web app on android
It's not really amazing
Mostly due to discord being lazy with mobile discord web
yeah iām not surprised
really? how would that be done? I am guessing that would require jailbreak?
Yes itās sideloaded
You can have both the modded version and the stock version installed alongside each other
Technically Enmity is a jb tweak, but itās fairly trivial to inject it into Discord and redistribute modified IPAs, which is exactly what happens
Is there a version of vencord that works with enmity?
What
Vencord and Enmity are two completely different mods
There is no compatibility between the two
Vencordās entire premise doesnāt work in the mobile apps
oop ok
Could work, but would be stupid as fuck
Plaintext patches arenāt really viable when your JS is all Hermes bytecode
how can I properly trace where props are coming from?
the call stack just points me to React's bundle 
because you're looking at a class component
the props are passed at instance creation time
renderBody is called way later
you need to put a breakpoint in the constructor, due to discords class transform its likely gonna be a plain function
@next stone
I did at that point in time
I switch my discord language occasionally to spice it up a bit and most germanic languages are similar enough for me to understand it
freaky^^
think iāve seen you cover .fr as well^^
i also used to switch my UIs to langs i was learning (.fr & .es)
but never got so adventurous as to use langs that are just similar to mine haha
give me a second, I'm not sure which of these things is the constructor
based on the limited info I have, the code u have looks like this
function a() {
...
}
var i = a.prototype;
i.renderBody = function()... ```
a is the constructor in this case
why donāt yall give some of dcās functions self-documenting names to make traces etc. more readable?
...what? 
I can't tell if you're joking
ah yes let us magically add context that doesn't exist
the inverse of minifying
how are we supposed to rename discords names
lmfao
i thought that would work with the regex patching
oh, didnāt think that far lol
silly
fr
Also Z1 is a function from our code
unless
cause our code is minified too
ig you could also regex all the calls, no?
if you look at the error in the console and enable source maps you get the real name
āxD
yarn for discord
but only for vencord, right?
unminify regex
going on the discord client mod bingo sheet
Lmfao
actually so true
Honestly someone should make a built-in sharex server
xD

lol someone is upset
wtf is a sharex server
you will stop using fake names
Search sharex server on GitHub
Otherwise I'll have to open GitHub app
Ahh fuck you I'm opening
search moon landing fake on Google
search rotund balls on google
search twinks frotting on google
Maybe I fucking will
š
YES
NO
oh to be a twink frotting
fine
Fawn about to be introduced to a whole new world
thatās not frotting, Google š¤Ø
nah he's a gay little gremlin he consumes that shit daily
same
Damn wtf
... why
lmfao
yop its real
i found out when i had to do generics once
actually so true
You can use static analysis from typescript with the // @ts-check on top of the file
Or use a jsconfig.json
Alright... So... I dont know if this is the right channel BUT hear me out..
I've never coded shit for Discord Mods and have a big respect for anybody that is willing to put up with having to constantly fix their plugins after discords great updates
But I have a single Plugin from BD that is the only reason I just cant switch over to Vencord even tho BD is crashing every 2 mins
What would someone realistically charge to port https://github.com/Dastan21/BDAddons/blob/main/plugins/FavoriteMedia/FavoriteMedia.plugin.js over to Vencord now that third party plugins are a thing?
(the functionality of the plugin is basically to add favourites like the gif ones to all media, be it audio, mp4's or pics)
side note: only for pics, you can make them favāable by appending ?.gif:
https://cdn.discordapp.com/attachments/1015073917938966568/1069070207156490310/er1CzKF.webp
https://cdn.discordapp.com/attachments/1015073917938966568/1069070207156490310/er1CzKF.webp?.gif
any chance I could get a review on async message events pr
I can review it tomorrow
sweet, thx
merge
vscode uses ts engine to eval jsdoc p sure
but jsdoc more clunky
there should be a tool that converts ts to jsdoced js
glad you find it useful!
just curious, is there a reason not to use promisable? the type-fest library is already in the dependencies last i checked
type-fest
glorious name
@dull magnet this guy will take vencord down with his innovations
it's something too simple to import from a dependency
well isnt it better to use Promise instead of PromiseLike
why would it be
they also mean Promiseable
Promiseable is a utility type that means Promise<T> or T
no it means T or PromiseLike<T>
aight
where was the patchhelper again?
build in devmode
pnpm build --watch
true
alright fixed the chat bar icon

@austere gulch you will review patch
find: ".activeCommandOption",
replacement: {
match: /(.)\.push.{1,50}\(.{1,3},\{.{1,30}\},"gift"\)\)/,
replace: "$&;try{$1.push($self.chatBarIcon())}catch{}",
}
you will love
this makes no sense
this is failing
but I didnt even touch the build function
and it works fine If I build using the cmd
oh got it
what was it?
it was something else failing
pretty easy if youre smart
electron is a framework not a language
though u dont need to kno much about it
@dull magnet I've got branchs support working, all that's left is to make a release releases tag (like: https://github.com/Vendicated/Vencord/releases/tag/release) and somehow upload the assets
it works completely with git already
I'm gonna make a pr
is there already some easy way to patch context menus?
specifically the GuildContextMenu
yes, soon
context api coming soon
^ alr left server
Hiya, i'm a bit confused about how components work
i see a lot of plugins that just put normal html in the return of a function
for instance in the MemberCount plugin
when i try to do it it yells at me though 
is the file extension .tsx instead of .ts?
wy
also heads up you cant use components at the top level, they have to be within a function
yee i'm seeing that from looking at other plugins
that's jsx btw
huh what then?
huh
Vencord.Webpack.Common.SelectedGuildStore.getGuildId()
huh
just a question
what do you mean
like a button or something to see the last message deleted
nope
and there is no gameactivity toogle ?
is it a specific activity you dont want to show
no like u click on a button and ur game activity is not showing anymore
I know, but why do you want it to not show
do you want to disable it when you are playing a specific game?
idk sometimes i toogle it to don't play with people
is it just me or is the powercord api pretty weird
there is only IgnoreActivities which lets you not show the status for activities you select
ok ok
if i create a plugin i can have it instantly
what
having a look at a plugin i want to translate, guy makes direct calls to the inject method
or there is a verification ?
old powercord?
yes it is
you open a pull request to the repo
if it's merged then it turns into an official plugin
wdym direct calls lol
yeah so there is verification i can not make selfplugin
inject('better-folders-guildsTree', GuildsTreeStore, 'getGuildsTree', (_, res) => {
const ret = new GuildsTree()
ret.root.children = res.root.children.filter(e => props.guildFolders.includes(e.id))
ret.nodes = props.guildFolders.map(id => res.nodes[id])
return ret
})
const { inject, uninject } = require('powercord/injector')
you can if you install using the power user method
which you are gonna need anyways to make plugins
well that's just monkey patching
oh yes
how can i have it ?
it's how better discord does it too
yes but why is he using the inject method
inject is powercord patcher
which file is it in lol
its just monkey patch
should've been called XC_MethodHook 
it replaces functions
ahhhhhhh
basically monkey patch replaces functions, while vencord uses regex matching to insert your code inside the original function
btw if youre porting jubys betterfolders
he already ported that himself lol
i kind of just want to port the folder in a second row
ah š
can we use multiple theme ?
yeah that's exactly what i want
good to know i won't have to do that myself
that does not respond to my question
nice nice
that answers the other question you asked
and yes you can.
oh thx thx
guess i'll compile this myself for now until it's merged
how ?
simply use multiple links?
paste each link in a new line
it would be nice if we could toggle each theme
right now i'm just breaking the link for the one i'm not currently using
yeah but a lil toggle would be cleaner
we need an array component
maybe i'll make a PR for that
I think vap was working on that
ah okay
dang this is ugly
lol
I'm sorry for bothering you, do you have a rough idea of when this should be done?
ping didnāt track, Panda is not on the server anymore
you could dm him
is there a way to use animated gifs/pngs in a discord rpc? I stole found a way to do so for gifs but it requires the gifs to be uploaded to discord first @covert nimbus
by found a way I mean copied how it worked from replugged 
uhh no clue about animated but just putting in any image url should work, but discord is very inconsistent with that
that seems to be the case for images yeah, but for gifs, it shows the broken image icon or something
curious. mind looking around in the LocalActivityStore and showing me the asset?
Vencord.Webpack.findStore("LocalActivityStore") and try to find it
if it doesn't start with mp: then that is discord being bad at their job
where do I start
also now I happen to make gif urls work, maybe that one time I tried I provided a wrong gif link or something causing it to give the broken image icon š
if you want values, use __getLocalVars()
it'll return the current state of store
ofc you should use the functions if they're relevant
but they don't always do everything you want
but yeah, this
ok the assets starts with mp:, I guess mine before was a special case or just me being dumb, I thought I had to upload them first as an attachment here before I can use it, thank you for your time!
oh another issue I found, whenever updating the rpc (by that means clicking "Save and Close"), it stops running (?) and I have to toggle the plugin on and off again for it to display the rpc again
so it works when it starts with mp:?
I suppose so, yeah. I'm not sure now though since I can't replicate the problem I had yesterday using the same gif link I used
discordā¢ļø
(jsyk, discord is incredibly inconsistent when it comes to activities)
apparently yeah
, thank you for your time!
ok come back @covert nimbus I managed to fuck it up again
i have been summoned through an unholy ritual
what does thee seek,
turns out it's okay with external image links? but with any images/gifs sent from discord I suppose it gives the broken image symbol
oh uhh probably because it sees discord and goes "real"
h u h
......i have no clue
here's the gif https://cdn.discordapp.com/attachments/643456544255639552/1081817160466300948/cat.gif
I'll debug it when it's not 2AM 
ok ok, thank you for your time again
get some rest 
owo no?

this seems to be a workaround for gifs/image links that are from discord (cdn.discord.com/...)
basically they just regex'd the domain off and append mp: from there
@dull magnet so am i just modifying the build workflow to only delete unpacked and adding update_url to the manifest?
also wouldnt the manifest file also need pushing to the builds repo
no clue
because those are separate electron browser windows
we only patch the main one
it wouldn't be too hard to patch the other ones too though
**patcher.ts: **Lines 74-97
class BrowserWindow extends electron.BrowserWindow {
constructor(options: BrowserWindowConstructorOptions) {
if (options?.webPreferences?.preload && options.title) {
const original = options.webPreferences.preload;
options.webPreferences.preload = join(__dirname, "preload.js");
options.webPreferences.sandbox = false;
if (settings.frameless) {
options.frame = false;
} else if (process.platform === "win32" && settings.winNativeTitleBar) {
delete options.frame;
}
if (settings.transparent) {
options.transparent = true;
options.backgroundColor = "#00000000";
}
process.env.DISCORD_PRELOAD = original;
super(options);
initIpc(this);
} else super(options);
}
}
you need to edit this
line 76 in particular
**browserWindow.js: **Lines 17-35
if (opts.webContents) {
// General purpose popouts used by Discord
} else if (opts.webPreferences && opts.webPreferences.nodeIntegration) {
// Splash Screen
opts.webPreferences.preload = join(__dirname, './preloadSplash.js');
} else if (opts.webPreferences && opts.webPreferences.offscreen) {
// Overlay
originalPreload = opts.webPreferences.preload;
// opts.webPreferences.preload = join(__dirname, './preload.js');
} else if (opts.webPreferences && opts.webPreferences.preload) {
originalPreload = opts.webPreferences.preload;
if (opts.webPreferences.nativeWindowOpen) {
// Discord Client
opts.webPreferences.preload = join(__dirname, './preload.js');
opts.webPreferences.contextIsolation = false; // shrug
} else {
// Splash Screen on macOS (Host 0.0.262+) & Windows (Host 0.0.293 / 1.0.17+)
opts.webPreferences.preload = join(__dirname, './preloadSplash.js');
}
you can likely yoink these from powercord
"yoink" (steal)
heh cool
nvm
We could copy pasta the message context menu api from replugged now
no
we have a way more powerful context menu that can patch any context menu
but it's not merged yet
sooon
should I just yolo and merge @cedar olive
@dull magnet I've just completely tested https://github.com/Vendicated/Vencord/pull/582, can I merge?
@dull magnet q: are we gonna work on a devbuild store published extension or nah
any way to update discords electron version?
Openasar I think
hm i see
armcord is completely different
you will lack discord features
it's not just updating electron version
since when is openasar updating the electron version?
use canary
it uses very recent electron
canary doesn't display the electron version though? ._.
?
or do i need to install Vencord for that?
Just run a command in console to get it then
yea, just got the user agent, nvm
process.versions.electron
Oh yeah or that
electron 22.2.0, sheesh
if you got node integration enabled
should we actually do it?
then I can fix emote cloner too
hmm
I mean
try again if it fully works
my main concern is that it breaks some random lazy loaded chunk so we don't notice but then some poor guy crashes
either way we have crash handler now
yeah just merge if it works
waiting longer won't help
I mean unless u wanna do dev branch first but I still gotta look at that
yeah I will merge
I'm just resolving conflicts
not with the actual pr
just my permissions viewer edit using the api
oh
maybe I can improve the patch too
wait
does ur context menu pr check key length too
cause the key length check isn't there for funnies or similar it actually considerably improves performance
I tried
and it really does
**webpack.ts: **Line 97
// the length check makes search about 20% faster
the reason is that it allows us to not check non mangled stuff
the patch for adding the arguments
didnt get applied here
but did here
hmhm
one is jsx other is jsxs
my patch doesnt rely on that though
odd
wait
what
nvm
var r=(i(667294),i(322922))
EWW
horrible
ok we ready
what did u do
I fixed 
using the knowledge I learned yesterday
which means we lost no performance
first match the id, then find the variable being defined by it
I'm confused
with what
how does that work
^
match id -> lookbehind: .+? to match the id again, go back until it finds \i=
the minifier can put as many things before it
it's always gonna match correctly
????
it's matching the variable name before it
how does it go backward
"ahi".match(/hi(?<=(a)hi)/)
that's so strange
true
you can use \1 to refer to the first group
but it allows for better performance
okay I understand it now but this behaviour is so obscure
wdym?
\1 is a backreference
it is a placeholder for the first group that you can use in the regex
yeah fair
hmm
but I used it to match something super obscure somewhere
context menu api kinda does it
like a function that literally goes `a(b!=null?c:d,f)
I matched that with backreference
like I matched b=props.foo then used backref to match b
yeah you could use back reference to match the variable name + export name
it might indeed be faster
**reverseImageSearch.tsx: **Line 54
match: /(\i)=\i\.itemHref,.+?\(null!=\1\?\1:.{1,10}(?=\))/,
this is what I was talking about here
RegExp(`${id}(?<=(\\i)=.+?).*?\1\.${key}, \{`, "g"),
RegExp(`(?=${id}(?<=(\\i)=.+?).+?\\1\\.${key},{)`)
hmm why
why tf did it match l
that makes 0 sense
maybe u can't nest lookahead and lookbehind like that
wait
(?=
this should be (?<=
@cedar olive
I got it to work
I'm testing performance
RegExp(`(?=(${id}(?<=(\\i)=.+?).+?\\2\\.${key},{))\\1`, "g")
this is probably the best we can get
I used this too, to maybe increase performance a bit https://blog.stevenlevithan.com/archives/mimic-atomic-groups
So, I was messing around with RegexBuddy and discovered that capturing groups work inside lookarounds (e.g., "(?=(captured))"), even though, of course, lookarounds only match a position. Consider that by using this technique, you can return text to your application (using backreferences) which wasn't contained within your actual match (backrefer...
most patches take 0.2ms
giant files take like 15ms
wait
I got it better I think
then we dont have to insert the match
nvm I made it worse
I will use this one
done
but comment what it does
that regex is mega on drugs
if it works properly and isn't slow yeah
now there is
badd
jsdoc
ah ke
@dull magnet great just found out that regex I did doesnt work as global
gonna have to revert to this one
replacement: [{
match: RegExp(`${id}(?<=(\\i)=.+?).+$`),
replace: (code, varName) => {
const regex = RegExp(`${key},{(?<=${varName}\\.${key},{)`, "g");
return code.replace(regex, "$&contextMenuApiArguments:arguments,");
}
}]
god it's indeed slower
welp can't do much
I'll wait for what you want to do
if anything you can merge with this lol https://github.com/Vendicated/Vencord/pull/477
(I'm very confident it works correctly and it has the necessary fix)
hi with my friend (umm ..boyfriend) we made an api for bubble gifs we thought it would be nice to make a slash plugin or something like that
https://bubbles.octozu.xyz/doc
someone can tell me where to start for make plugin ?
thank you very much i will read all this !
what's a bubble gif
this is bubbles gif
oh speech bubble
there is/was a plugin in the works to generate those on client side
how th does that api work
you need to add a tag and maybe more according to docs
yees
I try to do it anyway?
the goal and select the category with the command /
and you cand add param nsfw and set true or false
by default it is false
what do you think of the idea ?
hummm a coinciende
yes i will try
you don't
damn
what's your use case
calling wikipedia api
what's the endpoint
the actual endpoint you're calling
??? don't be an asshole @cosmic mortar
im not gonna interact
vban 7 @cosmic mortar toxic
Done!
what are my options ven
running discord in insecure mode
apparently you need to pass origin=* as query parameter
fetch(`https://cors-bypass.efu-cors-bypass.workers.dev/https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&formatversion=2&srsearch=${word}`)

alr
I need to make vencord run discord in insecure mod
it will solve all of this corse proxy thing
happier developers
alright thank you ven <3
did you know that guy or was he just a weirdo @opal fern
i called him retarded, so i did kind of started it
alr
in samu's defence he was in fact dumb
fellas is it communist to hate rich people for being horrible people
but yeah be nice no need to get so aggressive just cause someone is stupid

fellas if it is communist to hate rich people for being horrible people, I am communist and I don't care
Figured out I think
@dull magnet would a plugin like this be merged?
Searches wikipedia for articles that are similar to a keyword
ill choose to not read that
real
@dull magnet what do you think?
ven thinks it should be mergede after 8 months
I started to try to make the plugin, and well there is no real way to make commands / with parameters currently with the plugin command api no ?
ok just unlucky that every order i tried didn't have one x)
There are several things I don't understand and as I don't really know in ts well I can show my code here and ask for advice?
Yes, just make sure it's in a coffee block
import { ApplicationCommandOptionType, findOption } from "@api/Commands";
import definePlugin from "@utils/types";
const urls = {
hostname: "bubbles.octozu.xyz",
sfwRandom: "/api/random/all",
nsfwRandom: "/api/random/all?nsfw=true",
tags: "/api/tags",
};
export default definePlugin({
name: "Bubbles chat Gif",
description:
"This plugin is there to answer a GIF chat (to make as if it was the person above talking) there are several categories ",
authors: [
{
id: 360119696944660481n,
name: "Octozu",
},
{
id: 691413039156690994n,
name: "UwU",
},
{
id: 686166148882104337n,
name: "lambdagg",
},
],
dependencies: ["CommandsAPI"],
request: async function (path: string) {
const response = await fetch(`https://${urls.hostname}${path}`);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return "https://" + urls.hostname + response;
},
commands: [
{
name: "randombubbles",
description: "Send a Random bubbles gif",
options: [
{
name: "nsfw",
description: "Send a NSFW bubbles gif",
type: ApplicationCommandOptionType.BOOLEAN,
},
{
name: "category/tag",
description: "Send a bubbles gif from a category/tag",
type: ApplicationCommandOptionType.STRING,
},
],
execute(opts) {
return {
content: findOption(opts, "nsfw", false) ? this.request(urls.nsfwRandom) : this.request(urls.sfwRandom),
};
},
},
],
});
this is what I have done so far
and my problem is the request
you need to await it since it returns a promise
const BASE_URL = "https://bubbles.octozu.xyz";
const RANDOM = "/api/random/all";
...
async execute(opts) {
const url = new URL(RANDOM, BASE_URL);
url.searchParams.append("nsfw", findOption(opts, "nsfw", false));
return {
content: await this.request(url);
}
}
also that won't work because this refers to the wrong object so this.request is not what you want but typescript should have already told you
so the solution is to make request a top level function
This is what it looks like, it is correct ?
import { ApplicationCommandOptionType, findOption } from "@api/Commands";
import definePlugin from "@utils/types";
const BASE_URL = "https://bubbles.octozu.xyz";
const RANDOM = "/api/random/all";
const NSFW_RANDOM = "/api/random/all?nsfw=true";
const TAGS = "/api/tags";
async function request(path: URL) {
const response = await fetch(`https://${BASE_URL}${path}`);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return await "https://" + BASE_URL + response;
}
export default definePlugin({
name: "Bubbles chat Gif",
description:
"This plugin is there to answer a GIF chat (to make as if it was the person above talking) there are several categories ",
authors: [
...
],
dependencies: ["CommandsAPI"],
commands: [
{
name: "randombubbles",
description: "Send a Random bubbles gif",
options: [
{
name: "nsfw",
description: "Send a NSFW bubbles gif",
type: ApplicationCommandOptionType.BOOLEAN,
},
{
name: "category/tag",
description: "Send a bubbles gif from a category/tag",
type: ApplicationCommandOptionType.STRING,
},
],
async execute(opts) {
const url = new URL(RANDOM, BASE_URL);
url.searchParams.append("nsfw", String(findOption(opts, "nsfw", false)));
return {
content: await request(url),
};
}
},
],
});
well i changed ur URL logic so you now just need
async function request(url: URL) {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const path = await response.text();
return new URL(path, BASE_URL);
}
a yes I'm stupid I had seen it
tf , I'm still having trouble reading, I'll read it all again xDD
ooof now the famous CORS .. x) I'll see tomorrow, but thank you for your help, it's very kind :3
gn c:
you need to fix cors on ur server
its really easy
do u use express or what do you use?
you just need to add header Access-Control-Allow-Origin: *
yes I know
i use spring boot
but tonight I'm tired
but thanks for telling me anyway
It works, but there's something I don't understand
It works when I put this ts return { content: await request(url)+"", }
but not that
return {
content: await request(url),
}```
okey thx
i somehow recall a custom regex backslash escape thing that matches discord minified variables
was i just hallucinating that? if not, what is it?
\i
oh cool, thanks
is there a better way of doing this
wait no this wouldn't work
hold on guh
wait this is a thing
nvm that seems to not do what i need
i think i got it, hold on
oh fuck it i give up, how do i add something up here?
(ignore the missing texture svg)
@dull magnet I just made ContextMenuAPI patches all take less than 1 ms using proxies
how
cuz we no longer have to match the entire module
that's what makes it so slow
. this
RegExp(`${id}(?<=(\\i)=.+?).+$`
let me add some comments lol
there
I applied the performance update here https://github.com/Vendicated/Vencord/pull/587
how do i colour this button properly
(placeholder texture until actual svg is made)
once again reading invisible-chat source saves me
css filter property
On the svg put fill="currentcolor" when you can just set color in css
there is really a problem that I can not solve otherwise everything is fine
when the request doesn't go well it just sends the text /
and here my code : https://pastebin.com/Aiuqh3sB
yep
working on vscode extension (yes test patch is in the wrong location i will fix)
still gotta actually implement the testing which I plan to do by running a websocket in the discord client inside an IS_DEV guard then connecting to that websocket from the extension
I also want to add test for all webpack find methods that ensure finds match exactly 1 function
https://github.com/Vencord/Companion if someone wants to contribute
might interest you @trail ginkgo
also i have no idea how vscode extensions api works but i figured out how to do code lens thingie and thats all i needed 
grr ts doesnt seem to have a way to walk the entire ast
like this is just direct children
oh wait
can just do this
????
why does walk only visit 6 but walk2 visits thousands
its the return whaaa
OHH
if you return a value it stops
huge
Nice
You can now install the Vencord vscode extension from https://marketplace.visualstudio.com/items?itemName=Vendicated.vencord-companion which is basically PatchHelper but inside vscode
It adds "Test Find" on any webpack finds that will test whether your filter finds exactly one module (and not more or none)
It adds "Test Patch" on any patches you define in definePlugin() that will test that your find is unique and your match and replace works and compiles correctly
To use it you also need to compile Vencord with DEV (aka pnpm build --watch or pnpm buildWeb --watch) and enable the "DevCompanion" plugin. Then just start Discord after vscode (or right click the user settings cog and click "Reconnect Dev Companion")
iām sorry but this is epic
can i do venc dev stuff with chrome or only standalone?
In all seriousness ven, how would i add custom plugins / edit them on web. I'd like to find out what prevents invisible chat from working.
csp probably
if on firefox or userscript
you can also just pnpm buildWeb to build web stuffs
oh interesting
what i'm plaintext patching on desktop doesnt seem to exist on web
(.)\.push.{1,50}\(\i,\{.{1,30}\},"gift"\)\)
would be cool if you added a chat icon api to avoid such issues
kinda too niche imo
wdym
but if someone makes it and its good then sure
i mean, 2 plugins rely on it and neither will work on web 
arghhh!! i'm so badd!
(i'm trying to make stupidly small ui tweaks)
is there a good way to do this?
What are you trying to do?
i'm trying to get rid of the toggle on required plugins since it's kind of misleading
maybe they should stay though
one thing that definitely doesn't make sense is that the whole card is dimmed
however, the settings and info buttons are clickable
before and after āØ! the padding looks weird though
ā
just conditionally render the toggle in the actual component, dont do stuff like this
{!disabled && <Switch .../>}
Yeah!
what happens when disabled is true? does it just render the false literal?
nothing
react won't render anything
ic
i'm also adding a notification preview button
is a fix annoying things pr fine?
lol
works fine
thats on web?
yep
chromium
IMO that should stay, its a disabled toggle anyway
where's the example for the context menu api again?
check emote cloner
it's redundant though
open a guild context menu, open react devtools, check nav id
or just take it from ViewIcons probably
thx
well other question, how do i add the react dev tools to the client
nvm
found
wait, is the guild header popout a context menu?
ye
btw is there hot reload for plugins or do i have to restart everytime i change something?
restart
hot reload isnt possible with how vencord patches work (i think)

ye, patches source
it doesn't look that great - but making the card enabled is an improvement
I disagree
would you still agree it's confusing having something which you can interact with appear as unavailable?
is there a way to add a context menu application command with a plugin?
how do 
u chads wanna add TabBar as a component to Webpack api?
@green vessel @dull magnet i'm working on a toggle for last.fm right now. just need to know, should the option be "Hide album art when missing," "Use placeholder when album art is missing," or maybe a dropdown saying "What should we show when there's no album art?" with the options of "Placeholder" or "Last.fm Logo"
i also want to implement code to check if the API itself is returning placeholder art and hide it.
which would make more sense in the context of the option.
@dull magnet as icon for a context menu entry
as I said just make it a react component
function Icon() {
return <svg><path /></svg>
}```
yea
This is what I've got right now.
I actually added a third option
Second option is the behavior before PR, third option is my original PR
way to go š
š hi [object Object]test
i'm trying to get compact mode to work with pronouns!
it would also be nice if it worked in the modal too
does it not work in compact mode?
not currently
the pronoundb extension (which also works for other sites, like Twitter) does the job:
it does! unfortunately the plugin in vencord doesn't though
the vencord plugin does the modal tho. So you get two PRONOUNS sections with the extension hehe
vencord enables discord's pronouns experiment which is risky tbh
(risky because it could disappear)
ig 3 once Discord rolls out the feature 
not quite because of this
it uses discord's
oh
i don't know how to access discord's settings though!
what settings?
lol
ay, pronouns are important, i donāt see the problem 
thereās prbly a css class, ima have a look
i was also considering a github-style option for the profile
there is!
but i thought it would be good to skip the logic if compact is disabled
otherwise it's doing it twice
yeah there are hundreds of occurrences of compact in the html with compact mode on, in cozy mode just tens
still though
(not sure wym)
yeah your if condition could be the existence of any compact-modeāonly class in the dom
hmm, well it currently just has the message object
it =?
the function
whatās the msg obj? feel free to paste code if you like^^
ah nvm
well the dom is always at hand
sec, iāll write the condition
The right thing to do would be to remove the logic that checks for compact mode
and let the browserās css engine handle it?
i haven't done that yet!
for the component in the user modal it's easy, there is aready a patch that is in the same place that logic is
no I mean the logic inside discord
ohh
oh, the one which hides the pronouns for compact mode?
well then you'd have two timestamps
the timestamps being different stops it from working
that sounds a bit roundabout
well in compact mode it should probably appear to the right of the username instead of the left
tho i havenāt thought it through (or even know much about how all this works)
you can see the existing code
i'm just trying to improve it
it's by TymƦn (i am not a lame face)!
I know
ok i just had to say that
how are you adding it when it's compact mode though
by adding a child next to the username component
I see
the username component is the same in both modes
actually a toggle for that would be nice.
But baseline could be one of the two.
- right: consistent with pronoundb extension
- left: user has choice: can toggle by switching between extension & plugin
hmm i guess the surrounding code probably already checks compact
yes, it's a var called c
iād suggest adding it either way and making it display:none via css for compact mode. That way the mod can be modded
hmm
also itās v simple; also portable to other mod techs that donāt rely on regex patching
i don't want the code to run at all
why?
well if you're not in compact mode, fetchPronouns will presumably be run twice
but after the first request per user that just accesses a cache, right?
like, you donāt send a request to the pronounsdb server for every single msg?
but the selector is kind of random
:P i wasn't sure if it cached the fact a request was sent but it does
[class*=compact] on the right element would surely work. Maybe thereās a slightly better approach. i can look into that if you like
doesn't the class have random chars though?
yeah, we only match on the constant part in the front
*= means anywhere in the attribute: *compact*
i wish i had known that earlier
i tried making a dark theme for google extension some years ago and didn't know this!
since recently it can even go both ways in the dom hierarchy with :has()
ah, i've defintely needed that at times
havenāt we all
^^
i did know about that but last time i wanted to use it no browser could
how can you add a css file?
yup, great new times!
- has()!
(2. ai taking over all (super)human work)
yay!
i think with <link> (or <rel>?)
iād just gotta ~~google ~~bing lol
oh, right hehe
yeah idk that, i havenāt made a plugin yet. But iāll look into one right now and return with the answer 
**index.ts: **Line 19
import "./shiki.css";
gg! :DD
yeah, the pronoundb extension sadly also has slight flickering problems. i donāt usually notice them anymore, but would ofc be nice to polish them out. Not necessarily before publishing your first release version tho š
iām thinking with the component source patching approach this should be fixable
thanks! hopefully the plugin is slightly better now
it feels quite janky :P
it's less visible in cozy mode
good. Thatās the important mode. ||;)||
still, it shifts the messages a tiny bit
cw: i guess it flashes a bit :P
another thing i'd like to do to improve it is add it to the profile dialog!
currently it only shows in the popout
you mean it would update the pronoundb entry?
oh the global profile
still have that shown
)










