#🧩-plugin-development

1 messages · Page 81 of 1

quick zephyr
#

agony trying to tell them apart

#

good call btw

swift delta
quick zephyr
#

yeah but the alternative is giving them their own lines

#

like client themes

#

doesnt look good imo

#

and you cant resize the color picker like i originally wanted

#

you'd need to patch it .-.

swift delta
#

I’m not hating. I’m just laughing.

prisma pebble
#

Hello,
I've been working on a plugin, that, after processing some files, adds them to the current channel, so the user can optionally add a message and then send it. This worked quite well until recently, and i have no idea why it stopped.
Here's the code in question

/**
 * A wrapper for adding attachments to a channel.
 * @param files The files to attach
 * @param channelId The channel to attach them to
 */
export function addAttachments(files: File[], channelId: string) {
    UploadHandler.promptToUpload(files, ChannelStore.getChannel(channelId), DraftType.ChannelMessage);
}

And looking into the debugger it seems to receive the things it needs (see image below).
However nothing appears in the channel. And this despite UploadHandler.promptToUpload seemingly working in other Vencord plugins.
As I can't seem to figure out myself what I'm doing wrong, I'm asking here. Anyone got a clue or a tip?

quick zephyr
quick zephyr
#

😭

fallen sandal
#

just stack them in a 2x2 grid so nothing is too wide

quick zephyr
#

oh yeah I could do that huh

#

hm that would mean I would have to squash them into a single OptionType.COMPONENT though wouldnt it

#

ill look into it tmrw

prisma pebble
# prisma pebble Hello, I've been working on a plugin, that, after processing some files, adds th...

fixed by using the upload manager instead

/**
 * A wrapper for adding attachments to a channel.
 * @param files The files to attach
 * @param channelId The channel to attach them to
 */
export function addAttachments(files: File[], channelId: string) {
    // UploadHandler.promptToUpload(files, ChannelStore.getChannel(channelId), DraftType.ChannelMessage);
    // Vencord.Webpack.findByProps("addFiles")
    UploadManager.addFiles({
        channelId: channelId,
        draftType: DraftType.ChannelMessage,
        files: files.map(e => ({
            file: e,
            isThumbnail: false,
            platform: 1 // WHAT DOES THIS MEAN.
        })),
        showLargeMessageDialog: false
    });
}

I'm still baffled by why it didn't work with the simple other function anymore

cedar olive
#

promptToUpload got broken recently

#

but it has been already fixed

#

vencord was finding the wrong function which did nothing

quick zephyr
# quick zephyr ill look into it tmrw

looked into it today instead :^) and I have no clue how to change multiple different settings from inside a component. nothing I do updates the settings :(

humble tulip
#

Are you using setValue on the props passed into the settings component?

#

It'll only change the settings when you click save this way

quick zephyr
#

that props wont have all 4 other settings

humble tulip
#

You can use useSettings if you need the others but they won't update until you click save either

#

If you need access to the other settings in realtime they're gonna need to be custom too

humble tulip
quick zephyr
#

got it working somehow

const [value, setValue] = useState(settings.store.restyleExpired);

function updateSetting(newValue) {
    console.log(`Updating setting restyleExpired to ${newValue}`);
    settings.store.restyleExpired = newValue;
}
...
<ColorPicker
    color={value}
    onChange={newValue => {
        setValue(newValue);
        updateSetting(newValue);
    }}
    showEyeDropper={false}
/>
#

updates live too. wasnt expecting that

#

previous 1 entry per version didnt

humble tulip
#

Nice

#

Setting on settings.store directly means it'll update the setting live as you change it but it means the cancel button on the settings modal won't really do anything

prisma pebble
# cedar olive were you up to date

just checked it manually, I wasn't, even though git pull told me it was up to date... fixed it now, that was certainly confusing how i got there...

quick zephyr
humble tulip
#

use setValue from the custom component props, it's basically just a buffer that holds the new settings value to be applied when you click save

#

But you'll probably have to have one overall setting that contains the individual ones

quick zephyr
#

yeah thats the issue rn

#

guess I could do a comma separated list

humble tulip
#

You can always just have a colours object as a single setting with the four colour settings as properties of that

#

That's what I do for the timestamp formats

quick zephyr
#

can I see how that object looks

humble tulip
#

You might have to use withPrivateSettings for ts to know that settings.store contains that

#

Smh i've fucked up my plugin somehow with this previewer change I made so the settings keep resetting

#

instantFormats is the same as formats when it's working normally

quick zephyr
#

and thats just a setting in definePluginSettings?

humble tulip
#

Yeah

quick zephyr
#

doesnt it yell at you if you try to use options that are built in

#

oh optiontype.custom?

humble tulip
#

Yeah

#

That one component option manages the format settings object and I just put all my settings on that

quick zephyr
#

can custom still have a component argument

humble tulip
#

Oh not custom sorry

quick zephyr
#

huh

humble tulip
#

I mix up custom and component

quick zephyr
#

I dont like private for this because I cant set defaults

#

rn I just have them set as hidden: true

humble tulip
#

Yeah I do the defaults manually

humble tulip
pearl stag
#

are settings from settings.use mutable?

quick zephyr
#

ok yeah just went with a comma separated list

export function parseRestyleValue(restyleValue: string): (number | null)[] {
    let colorArray = restyleValue?.split(",").map(color => color === "null" ? null : Number(color));
    if (!colorArray || colorArray.length < 4) colorArray = defaultStylesArray;
    return colorArray;
}

const defaultStyleValues = "2842239,6105983,8334124,2368553";
const defaultStyleValuesParsed = parseRestyleValue(defaultStyleValues);
const [defaultUnclaimed, defaultClaimed, defaultIgnored, defaultExpired] = defaultStyleValuesParsed;
const defaultStylesArray = [Number(defaultUnclaimed), Number(defaultClaimed), Number(defaultIgnored), Number(defaultExpired)];

function RestyleGrid(props: { setValue: (value: string) => void; }) {
    function serializeRestyleValue(colorArray: (number | null)[]) {
        return colorArray.map(color => color === null || color === undefined ? "null" : color).join(",");
    }

    function handleRestyleChange(colorIndex: number, newColorValue: number | null) {
        const colorArray = parseRestyleValue(value);
        colorArray[colorIndex] = newColorValue;
        const newRestyleValue = serializeRestyleValue(colorArray);
        setValue(newRestyleValue);
        props.setValue(newRestyleValue);
    }
#

would be kinda cool to see it update live but then if you click cancel have it revert but I dont think thats possible with how the settings props work

#

g r i d

humble tulip
quick zephyr
#

there's already an onChange

#

an onNoChange would be neat

#

could revert it in there

fallen sandal
#

speaking of settings is there a better way to do this without destroying settings for other platforms

like currently this linux setting is specifically for KDE but what if I wanna have a setting for a different DE but also persist the selected setting across DEs (and OS's but i split them)
(also i think rn its imossible to have the hidden value come from native cause its all async)

pearl stag
#

I think that'd allow more control over the data

#

I feel like there's a simple way tho

fallen sandal
#

@dull magnet is there a specific reason you made everything coming out of native be a function coerced into being async?

dull magnet
#

idk what you mean by "coerced"

#

there is sync and async ipc

#

you should avoid sync ipc

#

so it simply uses async ipc

fallen sandal
dull magnet
#

yes

#

cause async ipc

fallen sandal
#

mhm and i was wondering why only async

#

like yeah you should avoid sync ipc but its still useful sometimes

dull magnet
#

cause the api was designed that way

#

simple as

fallen sandal
#

im asking why

#

why why why

#

i need a static value out of native synchronously so cope your api is bad

honest stump
swift delta
quick zephyr
#

now to just test it for a bit to make sure nothing breaks :D

swift delta
#

Because it’s actually kinda cool

quick zephyr
#

originally unofficial cause it was minimal but then I started adding a lot of cool useful stuff so I'll make a pr once I test it for a bit and make sure nothing breaks. also need to see if I can find a loophole to discord not updating your available quests without a client restart or manually clicking to the quests tab

quick zephyr
#

So when you reload Discord, or when you navigate to /discovery/quests, the client makes a request to https://discord.com/api/v9/quests/@me to update the available Quests. (It also sends one to https://discord.com/api/v9/quests/decision?placement=1&client_heartbeat_session_id=xyz&client_ad_session_id=xyz but I'm not sure if that's relevant.)

I'm not really sure how the stores work but would manually requesting the quests/@me endpoint also update the QuestsStore or would I need to do something else, if that's even possible to manually trigger a store update?

The main problem is if you leave your Discord open for a long time then you'd never be giving the client time to update the Quests and so the plugin would be a bit behind as well. 🤔

fallen sandal
quick zephyr
#

dont think daddy discord would be a fan of me if I did that

fallen sandal
quick zephyr
#

you cant anyways. has to take as long as it needs to

fallen sandal
#

should be fine then

quick zephyr
#

???

fallen sandal
#

why are you even making this anyway

#

temporary decorations??

quick zephyr
#

cause I like quests :)

#

but the current way discord shows them is ass

fallen sandal
#

insane

quick zephyr
#

thanks

quick zephyr
# quick zephyr So when you reload Discord, or when you navigate to /discovery/quests, the clien...

figured out how to send an api request to quests/@me and retrieve the current quests. im assuming this wouldnt update the store but the way the plugin works it doesnt really need that until you go to the quests page which would update the store automatically anyways, so I can just make use of the results from quests/@me for the unclaimed quest indicator. would making auto fetching quests every hour with a setInterval a setting cross the line of the "no self bots" rule or is that reasonable enough? 🤔

pearl stag
#

@fallen sandal is there a specific reason to be fetching the avatar URL again in SendNativeNotification? avatarUrl is already passed as an argument in the function

    UserUtils.getUser(advancedNotification.messageRecord.author.id).then(user => {
        const avatar = user.getAvatarURL(basicNotification.guild_id, 256, false).replace(".webp", ".png");
normal wagon
normal wagon
# quick zephyr ?

the plugin you’re mentioning of adding an indicator for newly available quests it adds a color gradient and calls the api every time you start at an interval

#

i’m not entirely sure what that interval is cause i’ve only looked at the code once or twice

#

but it would add a button to the top of your server list and display all your quests that are available as a number and once clicked it’ll direct you to quests tab

#

when there’s no quests it’s white and when there is quests it’s rainbowish

quick zephyr
#

yeah found the repo. interesting. still prefer my implementation

normal wagon
quick zephyr
#

also potentially outdated looking at the routes they use

#

saw in another plugin the syntax is just

const { body } = await RestAPI.get({ url: "/quests/@me", retries: 3 });
#

wasnt sure how the authentication would work but guess it's automatic. thats nice

normal wagon
#

yeah with rest api it automatically passes your token in the requests i think you don’t need headers for most of discords api

quick zephyr
#

maybe I found a different project cause this one isnt making any api requests as far as I can tell

normal wagon
quick zephyr
#

ah

normal wagon
#

he said he made it for himself

humble tulip
quick zephyr
#

based on the repo I found thats a year old it used to be /channels/@me/questsMenu lol

quick zephyr
humble tulip
#

Just look at the object in dev tools I think

quick zephyr
#

how though

#

Vencord.Webpack has no Constants

humble tulip
#

If you have console shortcuts on then Constants should just be on the window object

#

I'm not at my PC so I'm not sure where it gets it from but you should be able to find it in the consoleshortcuts code if not

#

It's in @webpack/common

quick zephyr
#

QUESTS_CURRENT_QUESTS: "/quests/@me"

#

none for /discovery/quests smh

bronze dove
quick zephyr
#

my ctrl f didnt find it

bronze dove
#

search again

quick zephyr
#

I did

#

3 times

bronze dove
#

oh its not on the endpoints

#

well its somewhere bleh

quick zephyr
#

very cool joona thanks

bronze dove
#

its fine if you use a plain string for that though

fallen sandal
#

let me look

#

ok looking at the commit history user.getAvatarURL(basicNotification.guild_id, 256, false), was used before

#

dunno what's coming in through that avatarUrl var

pearl stag
#

It's smaller though

#

160x160

steady knot
#

@pearl stag why are you called ruotsin tunti 😭

pearl stag
#

Yup

steady knot
#

yop

pearl stag
#

I used to have a different profile picture

#

Since let's just say i didn't enjoy swedish as a subject

#

It used to make more sense

#

My old pfp was some guy screaming

#

Paired with the username

steady knot
#

lol

pearl stag
#

Then i updated my pfp in... 2023 i think

#

And didn't bother changing my username

#

Or nickname i guess

steady knot
#

that's fair

fallen sandal
#

@pearl stag the betterNotifications pr is still obviously under development so no its not gonna be approved for merge yet...

pearl stag
#

Just wondering if there's anything obvious to fix

fallen sandal
#

focus on that when all the features are in

swift delta
#

Question; Other then like building a custom element, maybe doing a <br /> to force it on to a different line, or a text wrap. Is there anyway to add a second line of text ...

rain shard
#

The text wraps, so you can write more text.

swift delta
#

Nah I wanna add a second line of text that can be easily customizable

humble tulip
#

Make description take a component as well as string suffoClueless

quick zephyr
#

Are the letters here consistent or are the webpack modules consistent? I'd like some way to note on my patches where they're found to make going back to them in the future easier.

empty sundial
quick zephyr
#

agony

vast karma
#

Obfuscated names are extremely unstable, they change with every update

empty sundial
#

ya

vast karma
#

Module ids are somewhat stable, sometimes last for months

empty sundial
#

whelp depends on the module itself and the find i guess

quick zephyr
#

well I guess patch helper is the solution here then

empty sundial
#

get a component?

quick zephyr
#

just know where the patch is made so I can go back to it later if I need to do anything with it

empty sundial
#

oh wait missed the second half of your message completely

quick zephyr
#

lol

empty sundial
#

i think thats enough to find the module that was patched

quick zephyr
#

yeah doing that too

hushed loom
quick zephyr
#

how do I go about doing that

hushed loom
#

Vencord companion can do that for you and it's really nice and easy to use.

vast karma
#

I don't format mine, just split each module to separate files

hushed loom
#

(My version of it)

quick zephyr
#

I have companion but only like 1 of the 4 buttons in vscode work SKULL_SKELETON

#

your version too

#

cause it was newer

hushed loom
hushed loom
quick zephyr
#

only test patch ever works. other 3 always error

hushed loom
quick zephyr
#

I need both?

hushed loom
#

I'm gonna go into the store. I'll help you out when I get back.

quick zephyr
#

thought yours was an alternative

hushed loom
quick zephyr
quick zephyr
#

plugin pretty much done at this point I just need Discord to send me a new quest while my discord is open to see if the auto fetch is working .-. chop chop discord

tropic ice
quick zephyr
#

ah

tropic ice
quick zephyr
#

readme just mentions the dev companion plugin so I wasnt aware

tropic ice
#

for some reason it isn't mentioned at all in the vscode extension

quick zephyr
#

lol

hushed loom
quick zephyr
#

Error: webpack.find found no module

best way to wait/check if webpack is ready?

quick zephyr
#

I want something to run when the plugin is enabled so I'm putting it in start() but if it's already enabled at startup it doesnt need to run (and cant cause the plugin is set to start at INIT)

#

it's calling RestAPI.get

#

or is there a way to tell the difference between startup and enabling it after the fact 🤔

#

looks like onceReady.then(() => {}); worked

#

oh I forgot the plugin forces a restart after enabling it anyways so this is pretty useless. Teehee

swift delta
#

Where is a good example for how to add a checkbox a VencordToolBox setting?

quick zephyr
#

doesn't look like you can atm

#

just assumes a MenuItem instead of MenuCheckboxItem

rain shard
#

Have skimmed through this channel but still not too sure, what would be the best course of action of modifying the logic of a component like the tooltip, or replacing it? My use case is changing the way tooltips anchor onto elements and their appearance behavior.

quick zephyr
#

sounds like CSS would work? if it's just about appearance

rain shard
quick zephyr
quick zephyr
#

though it would effect all tooltips

rain shard
#

The tooltips can spawn in all four directions (top left right bottom) so you can't hardcode an offset as an example

quick zephyr
#

what do you even want to do with it

rain shard
#

Move them so they're anchored closer to the element you're hovering over

quick zephyr
#
{
    find: "tooltipPremium});",
    replacement: {
        match: /spacing:\i(,nudgeAlignIntoViewport:)/,
        replace: "spacing:50$1"
    }
},
#

default is like 12 or smthn

#

inspecting the tooltip component is a pain since it's an on-hover only and if you pause with a breakpoint the components tab freezes SKULL_SKELETON

#

but if you unpause in the sources tab and dont mouse over the client the tooltip wont go away so it works

rain shard
unkempt hemlock
#

hey I have a request

#

could we remove the NoUnblockToJump plugin from the official plugins?

#

it was created by a now-deleted user, and also it never worked for me

#

always jumps to a random message

dull magnet
#

?

unkempt hemlock
quick zephyr
swift delta
quick zephyr
#

looked at some other plugins that do periodic api calls and it's only once an hour so hopefully it's fine

#

also a disableable setting

#

kinda less useful without it though cause you wont know when new quests are released otherwise

silk sorrel
#

@dull magnet hey there, in the ticket you mentioned reexporting stuff from @webpack/common. I tried your snippet and ig it's not valid typescript syntax:

import { ChannelStore } from "@webpack/common";

export { ChannelStore: ChannelStore as MyChannelStore }
// Parsing error: ',' expected. eslint

I also tried declaring a local variable and exporting that:

import { ChannelStore } from "@webpack/common";

const _ChannelStore = ChannelStore as MyChannelStore;
export { _ChannelStore as ChannelStore };

But this seems to be causing some issues

should I just wrap it in proxyLazyWebpack/proxyLazy? Idk if that's bad practice but it stops the errors at least

dull magnet
#

oof
why is that not valid syntax lmao

silk sorrel
#

idk 😭

#

but is there any reason why it crashes when accessed indirectly
I thought it was just passing around the whole proxy object so it should't matter

tropic ice
#

does export { ChannelStore as MyChannelStore }; work?

#

what is the ChannelStore: for

humble tulip
#

You'd get an export named MyChannelStore I believe

#

I think ```ts
import { ChannelStore as OriginalStore } from "@webpack/common";

export const ChannelStore = OriginalStore as MyChannelStore;``` would work which is just a streamlined version of the second solution above

quick zephyr
#

what is that even doing

silk sorrel
# quick zephyr what is that even doing

redefining the store type and exporting it again under the same name
the types in @webpack/common and discord-types are outdated and I don't want to cast every time I use the store

quick zephyr
#

ah yeah I ran into the discord-types being outdated too

#

I just used as any lol

silk sorrel
#

😭

quick zephyr
#

just fork it and update it and then pr vencord to it thanks

silk sorrel
quick zephyr
#

Is there a way to patch a component but only my implementation of the component 🤔 I want to change a built-in string but not for every implementation across Discord, just mine.

humble tulip
#

Can you do anything to differentiate your one? For my preview timestamps I set the message ID to something only my preview messages would have so any others could be ignored

quick zephyr
#

hmmm

#

would changing the className help 🤔

humble tulip
#

If you can access it from your patch sure

quick zephyr
#

guess I could patch it based on my placeholder which I also changed?

bronze dove
#

Or just add a another prop

quick zephyr
#

oh right I can just add whatever huh

#

says it cant find my find smh

humble tulip
#

In your patch, is there anything you pass into a function or something that you could identify your own version and return early instead of doing whatever the patch does?

Like```$self.doThing(component);

doThing(component){
if(component.isMine) return;

// do thing
}```

#

I don't know what you're patching but if you can identify your own component you can just tell it not to do anything

quick zephyr
#

ah

#

I get it now. so I patch it for everyone but the patch just checks if it's mine and if not does the default

humble tulip
#

Yeah

quick zephyr
#

holy shit that was way more work than it needed to be

#
{
    find: '"onSearchChange",',
    replacement: [
        {
            match: /(\((\i),\i\){)(var{options:\i,)/,
            replace: "$1const vcDynamicDropdownNoResultsText=$2.noResultsText;$3"
        },
        {
            match: /((\i);return\(0,\i.\i\)\(\i,{)(loading:\i,)/,
            replace: "$1noResultsText:vcDynamicDropdownNoResultsText,$3"
        },
        {
            match: /(function \i\((\i)\){let{onSelect[^]*?)(\i.intl.string\(\i.\i\["[^"]+"\]\))/,
            replace: "$1$2.noResultsText??$3"
        }
    ]
},
quick zephyr
swift delta
# quick zephyr :)

I mean, as long as it doesn’t let you go under 30 minutes that’s actually kind of cool

#

Because I think if someone was to sell it checking too frequently than that might trigger the API for abuse

quick zephyr
swift delta
#

Noice

quick zephyr
#

gonna have other checks anyways to validate it

#

since you can edit settings manually

quick zephyr
#

speaking of getting rate limited SKULL_SKELETON

#

forgot to multiply by 1000

#

was making request every 1800ms not 1800s

#

wtf this is a new reward type

fallen sandal
#

digital PNG download

dull magnet
quick zephyr
#

oh that'd make sense

#

usually they specify ingame though

#

btw how do you upload assets for the readme? I know you can just drag an image into a comment on github then copy that markdown elsewhere but I notice all the existing plugins that have readme assets are attributed to the repo: https://github.com/Vendicated/Vencord/assets/... whereas the image I get is https://github.com/user-attachments/assets/....

also does the readme need to be basic? I notice a lot of plugins dont have readmes and those that do pretty much just have the tagline of the plugin and an image but I'd rather also explain all the settings if that's fine. 🤔

quick zephyr
dull magnet
#

i will redeem it for u

quick zephyr
dull magnet
#

u were too slow

quick zephyr
#

bro hacked into my discord and stole my code

quick zephyr
#

@humble tulip you have an onChange for your component setting, right?

humble tulip
#

I don't think so

quick zephyr
#

rip

humble tulip
#

When you save it just commits what you've passed to setValues

quick zephyr
#

mine are triggering twice

#

I also logged shikiCodeBlocks's onChange and that triggers twice too

#

cant fathom why

humble tulip
#

Maybe breakpoint it and see if you can see where it's being called twice in the stacks?

quick zephyr
#

like breakpoint the save button?

humble tulip
#

Or just your onChange, I dunno

rocky lynx
#

is there an example somewhere of how to add domains to csp with my plugin?

quick zephyr
# humble tulip Maybe breakpoint it and see if you can see where it's being called twice in the ...
private notifyListeners(pathStr: string, value: any, root: T) {
    const paths = pathStr.split(".");

    // Because we support any type of settings with OptionType.CUSTOM, and those objects get proxied recursively,
    // the path ends up including all the nested paths (plugins.pluginName.settingName.example.one).
    // So, we need to extract the top-level setting path (plugins.pluginName.settingName),
    // to be able to notify globalListeners and top-level setting name listeners (let { settingName } = settings.use(["settingName"]),
    // with the new value
    if (paths.length > 2 && paths[0] === "plugins") {
        const settingPath = paths.slice(0, 3);
        const settingPathStr = settingPath.join(".");
        const settingValue = settingPath.reduce((acc, curr) => acc[curr], root);

        this.globalListeners.forEach(cb => cb(root, settingPathStr));
        this.pathListeners.get(settingPathStr)?.forEach(cb => cb(settingValue));
    } else {
        this.globalListeners.forEach(cb => cb(root, pathStr));
    }

    // this.pathListeners.get(pathStr)?.forEach(cb => cb(value));
}

ok so the issue is the last line in SettingsStore.ts. Once I commented it out my onChange only gets called once and it does succeed updating the value. sooooo hmm

#

this is above my pay grade

swift delta
quick zephyr
#

tldr onChange for settings is being called twice. commenting out that last line fixed it for me but im not sure if that has other consequences.

humble tulip
#

Oh, it looks like setValue is onChange

quick zephyr
#

no setValue calls a temporary onChange which is independent in the settings modal

humble tulip
#

It looks like it's the same onChange that is called on all settings types

quick zephyr
#

well yeah but it's not the one you can optionally set on the setting

#

unless it is idk

#

all the plugin internals confuse me

#

this is what I meant

#

the setting component's on change is a wrapper for setTempSettings and is called any time the value changes while the modal is still open

#

not the same as the onChange you can pass in which is only called if you click save

humble tulip
#

Yeah I think you're right

#

Too many things with same names

#

When you add your own onChange it gets added as a SettingsStore listener, so yeah I guess it fires once for the plugins.pluginName path and once for plugins.pluginName.setting ts if (opt.onChange != null) { SettingsStore.addChangeListener(`plugins.${p.name}.${name}`, opt.onChange); }

quick zephyr
#

yeah. cant really understand what all that bit of code is doing though so idk if the last line was a mistake or is partially needed in some cases

#

logged it for my use case and the values of settingPathStr and pathStr were identical so idk

humble tulip
#

Yeah I was gonna say I'd be kinda confused on how it'd be calling plugins.pluginName because there would be nothing setting a listener with that key

#

I should just put an onChange on something and try things instead of speaking in hypotheticals

quick zephyr
#

it happens to shikicodeblocks too

humble tulip
#

lol every time my timestamps rerender (every second for every message because of relative time) and get the settings again it adds the change listener again

quick zephyr
#

lol

humble tulip
#

I think where it says ts if (paths.length > 2 && paths[0] === "plugins") { it just needs to be 3 instead, because this captures plugins.pluginName.settingName which is identical to the whole path and so the if block and the lone callback after both get the same listener

quick zephyr
#

setting it to 3 stopped my issue

humble tulip
#

I would make the change and PR but I can't be bothered testing a bunch of settings to make sure it doesn't break anything

quick zephyr
#

thats why I pinged nookies

humble tulip
#

I just looked through every use of onChange and it looks like nobody has ever used it for anything where it matters if it's called twice lol

#

So it's never been noticed

quick zephyr
#

yeah it has few uses

#

it sucks for me cause im stopping an interval then starting it again so what ends up happening is stop start stop start

humble tulip
#

Only took five months for the bug to be found

quick zephyr
#

im good at that. my only 3 merged prs were bugs(&adjacent) I found while trying to modify plugins SKULL_SKELETON

humble tulip
#

But I may as well just use settings.store instead since it rerenders every second

quick zephyr
dull magnet
#

uhhhh

#

can u share your settings code & component

quick zephyr
#

pretty much everything there down was us talking about it

#

we found the problematic code we just dont know what way would fix it without unintended side effects

#

most basic working example is shikicodeblock

#

if you add a log here you'll see it triggers twice when you change the setting

humble tulip
#

I don't think there should be side effects as the point of it is just to call the main setting's hooks if any nested properties update, and with length > 2 it's catching the main setting path

fiery berry
#

is there a better way of adding a CSP exception required by a plugin besides VencordNative.csp.requestAddOverride(), or is that the intended approach?

dull magnet
fiery berry
#

awesome, thanks

swift delta
rain shard
#

And the description text doesn't need to repeat the title text

quick zephyr
#

I'd recommend a color picker if you don't have any special input requirements

quick zephyr
quick zephyr
#

you could also just add the hashtag for the user instead of warning about it

quick zephyr
quick zephyr
#

also you misspelled color

quick zephyr
#

insane you spelled it both ways between the title and description

#

pop off

rain shard
#

Shouldn't Nsfw be uppercsse blobcatcozy

quick zephyr
#

gotta make a custom component for that

rain shard
#

I was joking

quick zephyr
#

I'm not. do it

swift delta
rain shard
#

I think you could make it a bit more clear by just saying you can use any CSS colour

quick zephyr
#

in my smyn pr I just mention the formats "hex(a), rgb(a), hsl(a)"

rain shard
#

Then the addendum about the hashtag isn't necessary

swift delta
#

And oklab

#

Soo…

quick zephyr
#

what's that

dull magnet
#

is it just css colour

swift delta
#

It’s the best CSS colour

dull magnet
quick zephyr
#

right

dull magnet
rain shard
#

hsl, hwb, lab, lch, oklch, lwb😭

swift delta
dull magnet
#

is the value used as css colour

swift delta
swift delta
rain shard
#

Using inches and milimeters as the CSS unit for my personal plugin

dull magnet
#

what kinda answer is that 😭

do you <Element color={thing} /> or do you parse it manually from js

#

if it's the former, just write something like
Supports all web colour formats (hex, rgb, hsl, etc)

dull magnet
#

if someone is smart enough to know what an oklab is they will also know that web colours includes oklab

#

normal users will just use hex

swift delta
swift delta
rain shard
#

(it's not fun though)

swift delta
#

Plus I prefer the plug-in anyways since all the customization abilities it gives you

#

Plus, it works in places where the snippet doesn’t work

#

Eg nsfw stages, and threads

#

You can also toggle it where you wanted to show and were you don’t

swift delta
rain shard
swift delta
silk sorrel
#

Not really if you're using Vencord components, but if you're using something extra like the rich chat editor it makes it easier to pass proper props without crashing your entire app every time
(Also users wont know how to stop crashes themselves, it's better ux to show an error box)

swift delta
#

Ight that answers my question

#

Thanks

dull magnet
#

if you wrap your component on an error boundary, the error boundary will catch the error

#

if your component can in any way error, you need an error boundary

but it's optional for things like modals because the crash recovery plugin can recover those by just closing the modal

fallen sandal
# swift delta

why are you using a text input instead of a colour picker for this?

fallen sandal
fallen sandal
#

??

fallen sandal
quick zephyr
#

ah thanks

fallen sandal
quick zephyr
#

spent half an hour trying to figure out why component isnt working
finally realize I was matching the component below the one I actually wanted

#

agony

#

-# (no this is not what it will look like I was just trying to get the upper badge to work)

green vessel
#

it'd be nice if plugins could add to the csp

#

in terms of userplugins and stuff

swift delta
#

Make a native.ts file and import the stuff

dull magnet
#

hä why are u assigning twice

#

it's just gonna use the second

#

image src includes connect src

green vessel
#

would you do like ImageSrc + ' ' + MediaSrc

#

or whatever

dull magnet
#

they're arrays

swift delta
#

I might be a bit stupid

green vessel
#

oh ic

#

so flatten them

#

got it thanks

#

does adding to media-src not do anything

empty sundial
green vessel
#
/*
 * Vencord, a Discord client mod
 * Copyright (c) 2025 Vendicated and contributors
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

import { ConnectSrc, CspPolicies } from "@main/csp";

CspPolicies["files.catbox.moe/"] = [...ConnectSrc, "media-src"];
empty sundial
#

reinject, restart

green vessel
#

i already restarted

#

does pnpm watch not do it

empty sundial
#

not with native

#

you need to rebuild

green vessel
#

got it

#

is there a onestop pnpm command to just reinject to a path

empty sundial
#

not sure about path, i just do
pnpm run build && pnpm run inject --branch canary

green vessel
#

working thanks

#

nothing like having wumpus vibe to the weeknd

#
/*
 * Vencord, a Discord client mod
 * Copyright (c) 2025 Vendicated and contributors
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

import { definePluginSettings } from "@api/Settings";
import definePlugin, { OptionType } from "@utils/types";

const settings = definePluginSettings({
    source: {
        description: "Source to replace the vibing mp3 with",
        type: OptionType.STRING,
        default: "https://files.catbox.moe/udwvp9.mp3",
        restartNeeded: false
    }
});

export default definePlugin({
    name: "Weeknd Wumpus",
    description: "have wumpus vibe to our lord and savior, The Weeknd",
    authors: [{ id: 1003477997728313405n, name: "Death" }],
    settings,
    patches: [
        {
            find: ".navigator.mediaDevices.enumerateDevices()",
            replacement: [{
                match: /\.src=(\i)/,
                replace: ".src=this.name==='vibing_wumpus'?$self.settings.store.source:$1"
            }]
        }
    ]
});
humble tulip
#

You don't need to reinject, just build and full restart, not reload

swift delta
#

Was about to say

indigo ferry
#

Is there any documentation on functions? I'm wondering if there's a way to detect if a current guild is in a folder and to collapse the folder

humble tulip
#

Stores.UserSettingsProtoStore.getGuildFolders() has a list of folders and the guild ids within them, could probably go off that

empty sundial
humble tulip
#

Then you just need to find what the onClick does when you toggle a folder

#

Even better

empty sundial
#

not sure exactly how youd do the expanding/collapsing though, never looked into that

indigo ferry
#

Alright, thank you

empty sundial
humble tulip
#

Yeah I was looking through them, just didn't see that one

#

Guess it would've been smart to look in BetterFolders

green vessel
#

is there some alternative localstorage

#

like hidden vencord config thing

#

i don't want to add more info to localstorage

dull magnet
green vessel
#

should clarify it's a userplugin and not for PR so i really don't care if stuff is in plaintext

dull magnet
green vessel
dull magnet
#

what...

green vessel
#

not encryption-type stuff, i already saw the methods on DiscordNative

dull magnet
#

safeStorage is what you want

green vessel
#

am i stupid

silk sorrel
acoustic nest
#

can I build a quest blocker

#

or is that a "css thing"

gloomy terrace
#

I guess it depends on what you want to do

#

Most things can be hidden with css

quick zephyr
#

block it how? cause in the pr I'm working on one of the features is disabling the popup by the user modal.

acoustic nest
#

I'd want to basically remove all references to quests

#

all of it

#

as if quests never even existed

#

well not wording but I mean functionally

#

idc if other unrelated UI stuff refers to it

#

thinking we could merge it with the yt ad block and create a generic upsell / ad blocker

#

maybe

#

could have a setting for blocking yt, one for blocking quests and perhaps one for blocking other types of upsells such as nitro etc

#

also, imo: "just use css" isn't really a good solution imo. few people know how to use or find the CSS for this stuff.

#

I imagine basically only power users and ppl in here would be able to do that then

#

which isn't great

#

if we wanna go the css route we should maybe have vencord ship with a couple prewritten CSS files you can enable / disable

#

bc expecting ppl to do it themselves is a bit much

#

and at that point it may be more thorough to go the JS route to avoid having to maintain the CSS

gloomy terrace
acoustic nest
#

well that still means only ppl here would be able to use it

#

we shouldn't require ppl join a server for ts

gloomy terrace
#

Make it a github import and you'll find it on there as well

acoustic nest
#

I hypothesize it may be the easiest if we somehow modify the code making the REST calls to nullify the data related to quests.
we wouldn't need to go anywhere else then, if we just cut out the quests data and make the client think there weren't any then we wouldn't need to inject into any UI

#

so no fiddling with css class names changing, or the components themselves changing, and if we do need to fiddle it'd be in a couple rest calls at most, which propagates throughout the client

#

though idt they would be changing the API layout on that much so fiddling would be very rare

gloomy terrace
#

I do agree that css has a shorter reach compared to an official plugin/feature, but I would personally still use the former since it's what I'm most familiar with
As for the other users, a post on the snippet channel, github import and uploading the theme to the BD website would be enough

acoustic nest
#

that still doesn't feel very accessible

#

and very power user centric

#

Joey Mainstream doesn't even know what a github is

#

also tbh I think CSS would be more work than the REST data modification

gloomy terrace
#

But they use a discord client modification, and if it's Vencord there is a direct link to the BD website themes section

acoustic nest
#

even as a power user it's just super inconvenient too

silk sorrel
acoustic nest
#

mm ye maybe

#

smtn to look into

acoustic nest
gloomy terrace
#

That's already what I'm doing with nvhhr's basic background theme lol

empty sundial
#

disable all of this shit and activity panel, quests, a lot of stuff just disappears except if you specifically look for it

vast karma
#

I would have yeeted quests in Anammox, if I had ever seen any

rocky lynx
#

is there an example somewhere of how to add domains to csp with my plugin?

acoustic nest
empty sundial
acoustic nest
#

Have had it disabled since quests came out

#

I still get them on ppls profiles n stuff

#

On activity feed etc

rain shard
#

I don't see them at all, so maybe it could be region based?

quick zephyr
#

any way to access the native ping sound player or is the best method creating an audio element and playing that? I tried break pointing a message being made while it pinged me but god I got like 1000 functions calls in before I gave up 😭

humble tulip
#

Have a look at the preview button in the notification sound settings, probably easier

bronze dove
quick zephyr
quick zephyr
#

ok note to self

#

dont fuck with SoundpackStore

#

or you'll brick your discord

#

had to delete the key from local storage after accidentally modifying it

oak sundial
#

💀

quick zephyr
#

I don't think man was meant to hijack the ping sound to use it elsewhere... guess ill look into the element method

#

OMG

#

that was so easy

#

lol

#
const Test = findByCodeLazy("Unable to find sound for pack name:");
Test("message1")
#
message1, deafen, undeafen, mute, unmute, disconnect, ptt_start, ptt_stop, user_join, user_leave, user_moved, call_calling, call_ringing, stream_started, stream_ended, stream_user_joined, stream_user_left, activity_launch, activity_end, activity_user_join, activity_user_left, reconnect

🤔

#

damn do NOT mess with SoundpackStore fr

#

just had to remove my discord folder from appdata local and roaming

#

client kept freezing on boot

#

nvm looks like breakpointing a specific part of the code also bricks your client

#

fun

#

oh dope it's not limited to those sounds

#
activity_end, activity_launch, activity_user_join, activity_user_left, asmr_message1, bit_message1, bop_message1, call_calling, call_ringing, call_ringing_beat, call_ringing_snow_halation, call_ringing_snowsgiving, clip_error, clip_save, ddr-down, ddr-left, ddr-right, ddr-up, deafen, discodo, disconnect, ducky_message1, halloween_call_calling, halloween_call_ringing, halloween_deafen, halloween_defean, halloween_disconnect, halloween_message1, halloween_mute, halloween_undeafen, halloween_undefean, halloween_unmute, halloween_user_join, halloween_user_leave, highfive_clap, highfive_whistle, human_man, lofi_message1, mention1, mention2, mention3, message1, message2, message3, mute, overlayunlock, poggermode_achievement_unlock, poggermode_applause, poggermode_enabled, poggermode_message_send, ptt_start, ptt_stop, reconnect, robot_man, stage_waiting, stream_ended, stream_started, stream_user_joined, stream_user_left, success, undeafen, unmute, user_join, user_leave, user_moved, vibing_wumpus, voice_filter_loopback_off, voice_filter_loopback_on, voice_filter_off, voice_filter_on, voice_filter_swap, winter_call_calling, winter_call_ringing, winter_deafen, winter_disconnect, winter_mute, winter_undeafen, winter_unmute, winter_user_join, winter_user_leave
#

aintnoway

#
{
    find: "could not play audio",
    replacement: {
        match: /(\i\(\d+\)\(".\/".concat\(this.name,".mp3"\)\))/,
        replace: "this.name.startsWith('https')?this.name:$1"
    }
},

that easy to get it to play urls. gotta host it on an allowed domain tho

#

is there a helper function built in for checking if urls meet the csp 🤔

hoary pilot
#

nop you'd have to make a native function to get the CSP

dull magnet
#

look at VencordNative

hoary pilot
#

i will document CSP

quick zephyr
#

well?

empty sundial
quick zephyr
acoustic nest
quick zephyr
#

yeah it's gonna be part of my quest plugin pr

#

I like quests so im adding enhancements.

acoustic nest
#

Le pog

quick zephyr
#

was all pretty easy to patch out

acoustic nest
quick zephyr
#

thats fetching quests

#

it blocks the request on startup

#

so quest store never gets populated

acoustic nest
#

Good

quick zephyr
#

if you try to go to quests tab it's blank

acoustic nest
#

Very nice

quick zephyr
#

you mentioned something about activity quests? I tried looking around my servers but couldnt see anything about that

acoustic nest
#

The right hand list of users' shenanigans

#

It has quests there often

#

And they're quite in your face

quick zephyr
#

I see. ill have to try to see if I can get it to work with an alt

#

if you see one take a pic and ping me so i know what to look for

acoustic nest
#

May be hard to bc it kinda requires friends on the account

#

Enough for some to have played a game that has a quest related to it

#

@quick zephyr

quick zephyr
#

will try to see if I can get it working with an alt then

quick zephyr
#

if you see quests anywhere else in the client lmk

acoustic nest
#

naisu

gloomy terrace
green vessel
#

does vencord have some easy way to open a modal with inputs

#

foudn @utils/modal thanks bye

quick zephyr
#

cooking?

elder forge
#

Hey just a question, have the source vencord version etc.

Why can it not find the modules?

oak sundial
#

no idea, need more info like the path this file is in for example

#

and what its called

#

and the error itself

elder forge
oak sundial
#

and what is this file called

elder forge
#

@quick zephyr Why did you react with an X? Is that the wrong filename + extension? I got this info from the wiki.

quick zephyr
#

I'm not familiar enough with ts to know for sure but all the files ive ever seen and worked with in the repo have been tsx

#

also I expected james to keep talking and didnt want to interupt which is why I reacted lol sorry

elder forge
#

Well TSX doesn't work either for some reason.

#

I tried both

bronze dove
elder forge
#

C:\Users\caly\Documents\Vencord\src\userplugins\testPlugin

bronze dove
#

Yeah but whats the opened the folder in vscode

bronze dove
#

Yeah open the vencord folder

elder forge
#

OHH

#

😭

median flare
#

for the life of me i cannot figure out how to get an external webpage to embed

#

Refused to load plugin data from 'https://www.example.com/' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'object-src' was not explicitly set, so 'default-src' is used as a fallback.

bronze dove
#

Add the header then duh

bronze dove
elder forge
#

How would I go about making a plugin, that add a slash command and when ran, it sends a message from your user?

hoary pilot
#

look at how similar plugins do it

median flare
bronze dove
#

thats more of a dynamic way, you probably want to enable it without user interaction since its required for your plugin to work

import { CspPolicies } from "@main/csp"
// native.ts
CspPolicies["isle.pizza"] = ["default-src", "object-src"]
median flare
#

putting it in native.ts

bronze dove
#

did you restart

median flare
#

oh silly me

#

yep, it works now, tysm

elder forge
bronze dove
#

spotify share commands

elder forge
#

How would I get every guild channel's name?

oak sundial
#

ChannelStore

elder forge
oak sundial
#

No

elder forge
#

Huh then how?

oak sundial
#

why does nobody search the code of vencord its like a single keybind

#

search ChannelStore

elder forge
oak sundial
#

the codebase

#

it will show up uses

empty sundial
#

thats why if you search enough youll find plugins that just use .ts files, they just dont need react and so have no reason to use .tsx

cosmic wigeon
#

I have a question.
Is it possible to export the entire dom and HTML discord?
So that it is easier to view the dom and HTML without having to use Ctrl + Shift + I?

#

I am asking because I need to pass this information on to someone else and for my own use.

cosmic wigeon
#

I apologize, English is not my native language and I wrote this without thinking.

rain shard
rain shard
#

What if they speak German?

dull magnet
#

then they would know english

#

anyway they're a malware skid so i'm gonna revoke their access

quick zephyr
#

ok finally finished rewrite. now to daily drive it for a bit to make sure nothing breaks :D

rain shard
#

Looking forward to it!

hoary pilot
#

oh my god this is so cute

acoustic nest
#

@quick zephyr can you link me the pr if/when you have it

quick zephyr
#

sure

#

im having this issue where if you hover over the button the pill slightly bumps. but it also happens on the DMs button. and it doesnt happen for guild pills. so im wondering if this is a me issue or a discord issue. can someone try hovering a guild and see if the pill "bumps". what I mean by that is that it doesnt just animate equally but also shifts by like a pixel. and then try the same thing with the dms button and see if it happens there?

#

well would you look at that I change addServerListElement(ServerListRenderPosition.Above, ... to addServerListElement(ServerListRenderPosition.In, ... and it doesn't bump anymore. Why is this platform so ass making me spend an hour trying to debug CSS.

#

how interesting if I remove the divider between the server list and the top buttons then all the guild pills bump too

#

so there's some fucky hackiness being done to account for the divider that doesnt get applied to the pills above it

#

omg max-height: 20px fixed it bless

#

for some reason it was animating up to like 20.3px

quick zephyr
#

why dev companion hitting me with "disallowed origin" 😭 man just let me debug a patch please

#

ok fixed it. agony

#

"rendered more/less hooks than last time" is despair

bright mantle
#

has anyone experimented with making a plugin that sends notifications to websockets?

i had this idea to make a plugin that sends notifs to OVRToolKit, so i can see them as popups while in vr

cedar olive
#

xsoverlay does it

bright mantle
cedar olive
#

well it uses websockets to send data

hushed loom
dull magnet
#

looks like it might be conflicting with the hover bar?

#

why are you even putting a dropdown there

#

what's that for

#

put it in a modal or tooltip or whatever

hushed loom
dull magnet
#

use state

#

show code

#

you're doing something wrong if it doesn't update

#

show 😭

quick zephyr
hushed loom
quick zephyr
dull magnet
#

that's normal

#

what do you expect?

quick zephyr
#

syntax like https://github.com/Vendicated/Vencord/assets/45497981/354220a4-09f3-4c5f-a28e-4b19ca775190

#

ton of plugins have this

dull magnet
#

github changed it because people abused this for scams

#

it makes it seem like that image comes from the repo

quick zephyr
#

how could they

dull magnet
dull magnet
#

I think you can understand why they changed the link format

quick zephyr
#

perhaps

dull magnet
#

it has nothing to do with skibidi toilet if that's what you mean

hushed loom
#

it's already over for you

quick zephyr
#

I havent seen that guy on my fyp in months. that arc of the internet is over

dull magnet
#

but like the song predates the toilet and was just appropriated

clear parcel
hushed loom
quick zephyr
#

I spend money in the shop and do quests, we are not the same

hushed loom
green oar
#

One message removed from a suspended account.

#

One message removed from a suspended account.

#

One message removed from a suspended account.

formal charm
green oar
lost gulch
green oar
#

One message removed from a suspended account.

lost gulch
#

it wont be

#

though i don't exactly have faith that it would be accepted, due to the fact that themes already serve that purpose already and a similar theming plugin has been rejected before for being overly complex

#

if it's not going to be it would be better for it to be some unofficial plugin for #1256395889354997771

green oar
meager ferry
#

anyone knows anything about discords new csp

#

its blocking all my external requests

#

is there some kinda vencord api to make requests now

#

im getting failed to fetch

vast karma
#

Discord hasn't changed anything (afaik), it's just that vencord stopped deleting the csp

chrome oak
#

how to edit a channel name? (or find out how to)

hoary pilot
green oar
#

One message removed from a suspended account.

hoary pilot
#
  • user generated domains: request override
    =====
  • predefined domains in a userplugin: add to csp with a native.ts
  • predefined domains in a plugin: edit the csp.ts file
#

csp.ts i think

dull magnet
#

yes

green oar
meager ferry
shy oxide
#

hi i created a plugin and need help making it comply with vencords rules?

oak sundial
foggy wyvern
#

Followup to #🏥-vencord-support-🏥 message

I'm trying to allow the ListenBrainz API in the CSP for my plugin (it's basically Last.fm). Am I missing something here? I've seen a couple of different ways of allowing a URL but none work. I'm using Vesktop and per docs I'm running pnpm build to update my changes, and the custom plugin is obviously loaded because it's in my logs.

I just added a file called native.ts and it looks like

import { CspPolicies, ConnectSrc } from "@main/csp";

CspPolicies["api.listenbrainz.org"] = ConnectSrc;
CspPolicies["listenbrainz.org"] = ConnectSrc;
// CspPolicies["api.listenbrainz.org"] = ["connect-src"];
// CspPolicies["listenbrainz.org"] = ["connect-src"];
index.tsx:231 Fetch API cannot load https://api.listenbrainz.org/1/user/qouesm/playing-now. Refused to connect because it violates the document's Content Security Policy.
#

this is correct

#

I can't confirm that native.ts is even loading but I'm not an expert here

hushed loom
#

this is what i did for my userplugin

proud parrotBOT
foggy wyvern
#

I've been refreshing but I just killed my Vesktop process and started it again to no avail

empty sundial
#

so there is no point in including it there

foggy wyvern
#

I was suspecting something like that because I couldn't find any others

hushed loom
#

wrong reply

empty sundial
foggy wyvern
#

just did

#

I'll even try killing vesktop again to see if that does anything

empty sundial
#

no errors during build?

foggy wyvern
#

nope

hushed loom
#

you also have to restart watch after adding a new native file for it to pick it up

foggy wyvern
#

elaborate?

#

I've just been running pnpm build

hushed loom
#

oh

foggy wyvern
#

maybe a pnpm build --watch

hushed loom
#

if you were never using pnpm watch or pnpm build --watch it doesn't matter

foggy wyvern
#

it's chill

#

but yea no dice with this current config

#

wait

#

that's a different url

#

hold on let me add that one

#

I don't know when that changed

#

Ok there's a third API I'm calling now that I'm gonna add but I had to kill Vesktop, not refresh, to get the 2nd one to take

#

oh jeez

#

so they show up now

#

but one of the URL's is like a specific archive.org server

#

so I've added https://archive.org but can I wildcard that URL? because that's gonna switch all the time surely

#

I see wildcards in the others, I'll try

#

It works!

#

for the record CspPolicies["https://*.*.archive.org"] = ConnectSrc; does not work but CspPolicies["https://*.archive.org"] = ConnectSrc; does

#

So let me post my solution

#

Just added a native.ts with the following:

import { CspPolicies, ConnectSrc } from "@main/csp";

CspPolicies["https://api.listenbrainz.org"] = ConnectSrc;
CspPolicies["https://musicbrainz.org"] = ConnectSrc;
CspPolicies["https://coverartarchive.org"] = ConnectSrc;
CspPolicies["https://archive.org"] = ConnectSrc;
CspPolicies["https://*.archive.org"] = ConnectSrc;

https://github.com/qouesm/vencord-listenbrainz-rpc/blob/main/native.ts

#

Thanks guys

dull magnet
quick zephyr
simple sandal
#

Hi I have a question regarding my plugin idea.

I want to make plugin where I can click a button which would bring up popup with all discord badges and you could select few of them (let's say Early Supporter Badge) and when you'll click Search, it will show all people in the server that you're currently in, which have the badge / badges that you selected.

Would it be possible to make and how hard could it?

Thanks

carmine spade
#

it's not even possible cuz you can't easily get all members of a server

simple sandal
#

why not

simple sandal
carmine spade
#

equally impossible

silk sorrel
#

You'd have to continuously fetch parts of the memberlist, which is limited to 300 members per query
This could take really long for servers with thousands of members, or get you banned

carmine spade
#

which is why i boiled it down to it being impossible

simple sandal
silk sorrel
simple sandal
#

so how could I get members with nice badges

#

as I'm a badge goblin and going manually through 100's of member profiles is quite annoying

#

just to find 1

carmine spade
simple sandal
#

lol

hushed loom
# simple sandal too deep in this shit

In economics and business decision-making, a sunk cost (also known as retrospective cost) is a cost that has already been incurred and cannot be recovered. Sunk costs are contrasted with prospective costs, which are future costs that may be avoided if action is taken. In other words, a sunk cost is a sum paid in the past that is no longer releva...

simple sandal
#

why's everything so fricking sensitive nowadays

#

youtube is getting blocked with normal words

#

just say it's total dog shit and whoever made the decision to do it should get fired

#

easy idk

#

so how could i get list with users with good badges

#

uhm why exactly?

silk sorrel
#

Why do u want to know which people have good badges

simple sandal
silk sorrel
#

Nah what does that mean 😭
Do you keep a spreadsheet or something

simple sandal
#

nah just dm people who's profile meets the criteria

silk sorrel
#

Are you blackmailing these people perchance /jk

simple sandal
#

it'll be easier than nagotiate a good price

#

😭

hushed loom
simple sandal
dull magnet
#

vban @simple sandal asking for help with buying accounts

shrewd tundraBOT
green vessel
austere mauve
#

nice badges @dull magnet can i buy ur account for 1 dollar

hoary pilot
#

nice badges @austere mauve can i buy ur account for 1 dollar

swift delta
#

nice badges @hoary pilot can i buy ur account for 1 dollar

hushed sable
#

nice badges @swift delta can i buy ur account for 1 dollar

normal wagon
#

nice badges @carmine spade can i buy ur account for 1 dollar

swift delta
#

Bro messed up the joke

silk sorrel
#

Laugh at this person

carmine spade
carmine spade
oak sundial
flat summit
#

Haiii hii hewwo, so basically I'm making custom plugin that integrates my rotary encoder on rpi2040 with discord to change volume of specific user

I tried changing localstore directly but nothing happened, so I guess there must be some function I need to call (or Im dumb and I did it incorrectly 3_) but I cannot find anything related to changing volume of a specific user (and muting specific user) in src code

hushed loom
flat summit
hushed loom
#

finding the component and seeing what it does when the slider is changed

flat summit
#

I can try tmrw cuz im in bed rn

hushed loom
#

if you can't find it, i will and send it to you in a bit

flat summit
#

Oke

#

So i guess you'll be faster than me getting up from bed and turning on pc lmao

#

Ty in advance

dull magnet
#

you need to find a component that does what you want, inspect it with react devtools, then check its handlers to see how it does it

then you can just replicate this in your own code

hushed loom
#

@flat summit the volume is passed through this function first, then set with wreq(846027).Z.setLocalVolume(userId, transofrmedVolume)

#

make a proper find for both functions

#

(i dont think vencord finds AudioActionCreators)

flat summit
#

ok i'm too dumb to understand how vencord works, going back to working with microelectronics lmao

#

i have suspicions that it would be easier for me to find it in ram using cheat engine and patching it like this 💀

#

the moment when c++ guy touches ts/js

quick zephyr
#

When I started working on my plugin I had no idea how it worked. Took about a week of pestering people here with questions and checking how other plugins did things to figure it all out.

flat summit
# quick zephyr When I started working on my plugin I had no idea how it worked. Took about a we...

i mean i got handed out which function i should use, i also found getVolume function using react components and i guess i could do the same for muting functionality.
Though i have no idea how to extract it from webpack chunk or reference it or do anything to it at all

And I don't have patience to dig thru vencord for a week especially because it was supposed to be shrimple plugin to change volume of a specific user with rotary encoder

quick zephyr
#

It always starts as a shrimple plugin. i just wanted a shortcut to quests... then you add and add and add and suddenly a week has gone by SKULL_SKELETON

#

you know how to inspect the components and find the code?

flat summit
# quick zephyr It always starts as a shrimple plugin. i just wanted a shortcut to quests... the...

i mean i dont even need any other functionality

I'm building "sound panel" cuz im lazy shit and i don't want to open windows volume mixer every time i want to change volume of an app, especially when I'm playing rhythm games like chunnithm, piu or sound voltex where app can crash when minimizing and i have keyboard put under monitor cuz those games have custom controllers which take up desk space

I have 8 rotary encoders communicating with driver on com port and everything works perfectly i just need one encoder for one annoying user in our discord as a meme and if i won't find out how to do it, i'll just mute him by hand if really needed so there's no additional stuff that can be added to functionality of this lmao

quick zephyr
#

how tf do you enable the bug icon/dev icon where the flux events are shown

#

dev mode enabled, react tools on, built with dev flag, dont see a relevant plugin, what am I missing 😭

swift delta
quick zephyr
#

yeah there it is

#

why on earth is that part of the experiments plugin

#

it's super relevant to plugin development 😭

swift delta
#

I am actually inclined to agree it should either be part of the companion plug-in or a setting toggle in the main Vencord setting page

quick zephyr
#

just dispatching this is enough. no function needed

#

once to mute, again to unmute

#

syntax will be different in a jsx file. ^ thats for dev console if you want to test it

quick zephyr
#

thats where I expected it to be lol

swift delta
flat summit
#

Clk is clockwise this is bound to f15
Dt I cclockwise this is bound to f14
Sw is switch - and we have this one (thank you again)

#

Muting itself is useful tho lmao

quick zephyr
#

could not tell you why but 100 equates to 100% in the client. 0 equates to 0%. but 1 equates to 19% and 2 equates to 25%

#

some fuckass scaling

#

can test it in dev console again to play around with values

quick zephyr
# swift delta iirc there is an toggle in the settings for the experiments plugin to enable it

if you wanna inspect events like this yourself you can do this and then go to the dispatcher tab. any time you do something in discord it'll probably show up there. then you can copy the data format to forge events. the events can be really fast and hard to track so after you do your thing you can click the checkbox to pause displaying new events to make finding the one you just made easier

#

-# oops sorry for ping if I did

empty sundial
quick zephyr
#

best plugin in yt music desktop is linear volume

#

nvm it's exponential volume lol

empty sundial
#

exactly

quick zephyr
#

@swift delta dont nerd me nerd

hushed loom
rain shard
#

Also, JS is a garbage collected language with very few fixed pointers so they can move around in RAM

flat summit
#

the driver and firmware is in low level c++

#

the discord plugin for connection with one of 8 rotary encoders is in TypeScript, like vencord

rain shard
#

I thought you were talking about your plugin to change the volume of the users 😭

flat summit
#

yes this too

#

Basically it works like that
I have a board with 8 rotary encoders
I want 1 of 8 rotary encoders to be bound to changing volume and muting one annoying user on discord.
The rest is bound to changing volume of specific games/programs

Firmware sends commands on COM5 channel, driver interprets it and changes volume of software/game on pc
For discord I made workaround and connected to HID, and I'm sending keyboard strokes (F13,F14,F15)

In discord my plugin adds keyDown event and I needed to know how do I implement functionality mentioned above

hushed loom
flat summit
#

lmao

#

also why should i create websocket for such simple thing

#

and on top of that

#

it's bound to non-existent keys anyways

flat summit
#

ok i have everything i wanted except for one thing

#

when i change volume it randomly spams in console with something like this

23:24:33.934 > [RTCConnection(undefined, default)] Media sink wants: {"any":100}
23:24:34.476 > F14 45
23:24:34.477 > [RTCConnection(undefined, default)] Media sink wants: {"85256":0,"any":100}
23:24:35.093 > F14 50
23:24:35.094 > [RTCConnection(undefined, default)] Media sink wants: {"any":100}
23:24:35.140 > F14 55
23:24:35.141 > [RTCConnection(undefined, default)] Media sink wants: {"85256":0,"any":100}
23:24:35.709 > F14 60
23:24:35.710 > [RTCConnection(undefined, default)] Media sink wants: {"any":100}
23:24:36.093 > F14 65
23:24:36.094 > [RTCConnection(undefined, default)] Media sink wants: {"85256":0,"any":100}
23:24:36.364 > F14 70
23:24:36.365 > [RTCConnection(undefined, default)] Media sink wants: {"any":100}
23:24:36.397 > F14 75
23:24:36.398 > [RTCConnection(undefined, default)] Media sink wants: {"85256":0,"any":100}
23:24:36.692 > F14 80
23:24:36.694 > [RTCConnection(undefined, default)] Media sink wants: {"any":100}
23:24:36.765 > F14 85
23:24:36.766 > [RTCConnection(undefined, default)] Media sink wants: {"85256":0,"any":100}

and user mute state flickers between toggled off/on

#

even tho f13/f14 doesn't mute an user

flat summit
#

so basically the same thing

#

it redirects me to this

hushed loom
flat summit
#

makes sense

#

still, when i change volume mute state flickers for some reason

#

tried adding debounce, nothing changed

#

maybe if i raise debounce in firmware

#

fixed a bug with double inputs but nothing changed anyways lmao

flat summit
#

ladies and gentlemen, it works

quick zephyr
quick zephyr
sharp egret
#

What's the best place to find decent documentation on what internal functions are called? In the plugin im making I want to be able to autimatically mute and un-mute DirectMessage channels, but I'm not sure what function it is I need to call. This is what I've tried but it does not seem to work:

// mute DM notif for N seconds
if (!msg.guild_id) {
    // DM case
    const CID = msg.channel_id;
    // create a mute config that ends in N seconds
    const muteConfig = {
        muted: true,
        muteConfig: {
            endTime: Date.now() + settings.store.muteTime * 1000 // ms
        }
    };
    NotificationSettings.updateChannelNotificationSettings(CID, muteConfig);
}
// empty case for servers because they don't need support
else {
    return;
}

My only experience with coding things related to discord is making discord bots, so it's also possible I've made a logic error somewhere, but it builds and injects without any errors, and the plugin does show up in the settings

dull magnet
#

what's NotificationSettings supposed to be

#

did you ai generate this code

sharp egret
sharp egret
dull magnet
#

so you asked ai to hallucinate up random garbage and think that will work

#

smart

dull magnet
#

stop asking ai

sharp egret
dull magnet
#

also what you're making is already a stock feature, no?

sharp egret
# dull magnet also what you're making is already a stock feature, no?

almost, but I want to automate it.

personal: || I have autism, so repeated loud noises is very difficult for me, and I have some friends who insist on writing the same sentence in like 5 different messages ||
so I want to be able to automatically mute a DM channel for 30 seconds after I get a message so I don't get spammed with loud noises

dull magnet
#

vp OnePing

shrewd tundraBOT
# dull magnet vp OnePing

If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping. Read the messages to reset the limit

Authors

ProffDea

sharp egret
#

But my original question still remains, where do I find the docs for all the functions? The vencord docs just include a guide on how to use git; but not anything about actually making plugins beyond the TS boilerplate (unless I've missed something). These are the docs I used: https://docs.vencord.dev/plugins/ are they the wrong ones?

And for the sake of clarity, these are the docs I tried summarizing: https://discord.com/developers/docs/reference

Vencord Docs

How to create plugins for Vencord

Discord Developer Portal

Build games, experiences, and integrations for millions of users on Discord.

sharp egret
# dull magnet stop asking ai

It's very often a great tool and most of my pupils use it to skim documentation. It's practically a requirement for some of the special needs kids we teach at my school. You probably shouldn't be so quick to judge people for using a tool you don't like :I

dull magnet
#

yes when it's based on real docs it can summarise

#

but asking it to hallucinate up "docs" for a proprietary undocumented codebase is just nonsense

empty sundial
#

discord.dev docs are only for the bot api

#

nothing else

#

it doesnt include functions, a lot of api routes only usable by bots and missing a ton of other api routes

silk sorrel
empty sundial
#

yea

#

discord.food documents the user side

sharp egret
empty sundial
# sharp egret There's an excellent study by UFMG in Brazil 🇧🇷 [https://arxiv.org/pdf/2408.14...

there isnt much to document in the vencord codebase, if you need info you can look through other vencord plugins
most of the work making a plugin goes into looking through the discord code to see what you need to call/modify, then writing patches or ts/react
the vencord side documentation for this would quite literally just be close to "matches find a webpack module, finds are regex finds that will be replaced with replace"

dull magnet
#

just drop it, this is a pointless discussion

#

don't come here with ai garbage or you will be kicked out of this channel, like #📖-info states

dull magnet
#

Kevin isn't ai

hushed sable