#🧩-plugin-development

1 messages · Page 58 of 1

tropic torrent
#

does forwardRef not work with vencord or just my skill issue, got this error from both react docs example and my component. (help i am going insane just doing this oncept stupidfuckingina (too dumb))

dull magnet
#

show code

#

i suspect you're accessing webpack modules too early

#

plugins run very early at a point where discord hasn't loaded yet

so if you use React.forwardRef on the top level it will fail

tropic torrent
#

which do you want cause its really all split up

dull magnet
#

just how you declare the component

tropic torrent
dull magnet
#

yep there's yor issue

#

you are using react on the top level, where it's not ready yet

#

wrap the react.forwardref call inside LazyComponent(() => {})

#
const CanvasComponent = LazyComponent(() => React.forwardRef(..
tropic torrent
#

thanks it works now

dull magnet
#

actually idk if that actually works cause lazy component doesn't forward ref itself

#

you could inline require the file

or

const getCanvasComponent = makeLazy(() => React.forwardRef())

// use
const CanvasComponent = getCanvasComponent()
<CanvasComponent />
tropic torrent
#

yeah actually referencing it now

amber mantle
#

nah was a self bot lol

#

anyone with e-z bio or some shidd in their bio is a skid doing that stuff

dull magnet
bright barn
#

If you are writing a plugin that depends on another plugin, how do you handle that import, considering the user may have installed the plugin in either the "plugins" or "userplugins" directory?

Currently I am using a very hacky try/catch to import from both locations, but I'm wondering if there's a common way to handle this?

For example

import { somethingINeed } from "plugins/foobar/something";

The above would fail if the user had installed "foobar" plugin into the userplugins directory.

viral roost
#

the easiest way to do this would be to just add the method you need to share between plugins to definePlugin and then just use window.Vencord.Plugins.YourPlugin?.yourMethod in the other plugin. typescript yells at you for this but you can ignore it, and i'm pretty sure some official plugins do this too

dull magnet
#

yes

bright barn
#

Does that mean the "foobar" plugin in my example above would need to be updated?

bright barn
cobalt radish
#

im back again trying to make a plugin, but im still struggling to make a patch

#

im trying to get the chat box, and try to add a simple onClick to it, but Im not getting very far =/

#

any tips for a noob on how to properly make a patch?

cobalt radish
#

Im using the companion, it is pretty nice, it says it found 3 matches, which is not good, is there a way to jump to those matches in the dev tools?

dull magnet
#

ctrl shift f

cobalt radish
#

I might be dumb lol

#

thanks

#

OHH YEEA, I did it =D

jovial field
#

when i run pnpm test it throws an error for invalid plugin because authors contains non-property access expressions, however my authors array is correct. does this mean it is possible* my plugin acting up?
i followed the current Plugins Guide

authors: [
    {
        id: 240125663619579905n,
        name: "vegard",
    },
],
dull magnet
#

authors: [Devs.vegard]

jovial field
#

ahh gotcha!

#

worked like a charm blobcatcool

cobalt radish
#

I managed to patch an element of the text box to place a onKeyUp event on it.. but Im trying to modify the content of the text input

#

so far I wasn't successful, changing the DOM does not really work well

#
 ComponentDispatch.dispatchToLastSubscribed("INSERT_TEXT", {
        rawText: text,
        plainText: text
    });

seems to work ok for adding text, but I actually want to remove the text...

dull magnet
#

findByProps("ComponentActions").ComponentActions

cobalt radish
#

turns out CLEAR_TEXT exist

#

thx bro

vale spear
cobalt radish
#

I want to create a shortcut with the keys ctrl + enter but this key combination sends the message.
I tried document.addEventListener("keydown", onKeydown); on start() and then e.preventDefault(); but it seems to be sending the message anyway
any idea of how to prevent the message from being sent when pressing this combination?

dull magnet
#

what do you actually want to achieve

cobalt radish
# dull magnet what do you actually want to achieve

Im making a grammar checker. when I type, it creates a box with the corrected text.
I want to transfer the text from the preview to the chat box when I press ctrl + enter.
it already works fine if I use a different shortcut that does not involve the key "enter" just because the enter key currently sends the text no matter what

safe glade
#

if you wanna do it with your approch could try ```js
function onKeydown(e) {
// [...]
e.preventDefault();
e.stopImmediatePropagation();
// [...]
}
document.addEventListener("keydown", onKeydown, true);

vee probably has a better idea though
cobalt radish
#

oh, good, stopImmediatePropagation might work

#

yep, that worked, thx

stiff cargo
#

@dull magnet is this good enough? :3

getAvatarStyles(src: string) {
    return Object.fromEntries([128, 256, 512, 1024, 2048, 4096]
        .map(size => [`--avatar-url-${size}`, `url(${src.replace(/\d+$/, size.toString())})`])
    );
},
#

actually sorry for the ping, I'll just push it and let you review it :D

balmy sky
#

What's the best way to let the user upload a file? i tried checking the way decor let's you upload decorations but it just uses a component from discord, whereas i only want a way to do the prompt

flint bronze
#

Look in src/utils/settingsSync.ts

balmy sky
#

Shit i forgot about that SKULL_SKELETON

#

Thanks!

balmy sky
#

I'm trying to use a library that requires nodejs 19 or higher for a plugin, running node --version says my version is already 19 but i still get an error when trying to build (Could not resolve "node:fs"), do project node versions exist? I've tried using a bunch of different versions (18, 19, 20, 21, 21) but i assume that vencord itself is just configured to use a different one and i don't know how to change it (in which case i'm pretty screwed)

#

My brain is NOT big enough for this shit

dull magnet
#

youre likely importing it in the browser side

#

browser cant use fs, etc

#

oh yeah dont use that library

#

you really dont need it

#

use fetch()

#

the docs are a bit confusing so i'll give u some pointers:
you need to use FormData

and send these params

Note: for anonymous uploads, simply don't supply a userhash.

File Uploads

reqtype="fileupload" userhash="####" fileToUpload=(file data here)

where for fileToUpload you'll want a blob with the bytes

balmy sky
#

The request is getting blocked by CORS 😭

dull magnet
#

damn

#

yeah you'll have to send it from nodejs then

#

but you still dont need the library

#

you can just copy paste your code to nodejs and itll work fine

#

native.ts file is how u can run code in nodejs

#

look at how other plugins use that file

balmy sky
#

Got it

#

Any specific plugin recommendations for me to look at?

dull magnet
#

all of them

balmy sky
# dull magnet all of them

ok i have everything set up with native but my plugin isn't in VencordNative.pluginHelpers, is there something i need to do to register it or smth?

dull magnet
#

restart discord fully

balmy sky
#

I am not very smart damn

#

For some reason if i build with the plugin in the folder, vesktop just doesn't open- if i run it from console instead this is the error log i get, i assume i did something wrong (code here)

jagged briar
#

if i had to guess cause your calling a function from index in native.ts

#

also dont do this

#

you dont want to load native every time you click the button

balmy sky
#

Can't read the error for the life of me tho

jagged briar
#

dont export it

balmy sky
#

Gfd

#

Alright i'll test that now

#

Well it opened

#

That's surely a good sign 💀

#

I now get this error when handleButtonClick gets called, i think it's an issue with the native upload function? i updated the gist with the new code

dull magnet
jagged briar
#

Fair enough

dull magnet
#

you're passing a File object which i guess cant be cloned

#

pass raw blob / UInt8Array via ipc

jagged briar
#

raw blobcatcozy

dull magnet
#

your fileToBlob should be in index.ts

balmy sky
#

Uhhh so yeah i just move filetoblob to index then pass the blob to native instead?

dull magnet
#

yes

balmy sky
#

Same error still

#

I updated the gist again blobcatcozy

dull magnet
#

make sure you full restart

balmy sky
#

I did

#

Yeah i just restarted my whole pc to be safe and it still happens

balmy sky
#

Update

#

Over the past 2 hours i have given myself brain damage and that's about it

green vessel
#

Real

next stone
#

I am updating an old PR and now find out that two components I need are lazy loaded. My old method of fetching these was using a plaintext patch that assigned the two components to $self, but that doesn't work anymore due to said lazy loading. What's the best method to do this now? Is it possible to force-load a module?

#

The components won't load until you open the settings views in which they're visible at least once, which isn't exactly ideal.

proud parrotBOT
# dull magnet we have a function for that https://github.com/Vendicated/Vencord/blob/main/src...

**CreateCategoryModal.tsx: **Line 36

export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\).{0,50}"UserSettings"/);

**CreateCategoryModal.tsx: **Lines 129-133

export const openCategoryModal = (categoryId: string | null, channelId: string | null) =>
    openModalLazy(async () => {
        await requireSettingsMenu();
        return modalProps => <NewCategoryModal categoryId={categoryId} modalProps={modalProps} initalChannelId={channelId} />;
    });
next stone
#

How do I figure out the arguments here?

dull magnet
#

basically whenever there's a lazy loaded chunk, some other module will have code for loading said chunk

it looks something like

Promise.all([n.e(1234), n.e(765)]).then(n.bind(...)) ```
#

you need to find the part in the code that does such loading of the module you need, find it via the first argument and then use a regex to capture the loading code (the function has a default regex that works for many cases)

next stone
#

found this

#

alright, got that at least

dull magnet
#

yep that's it

next stone
#

so the first argument is an array of finds that will end up finding the module containing this piece of code?

dull magnet
#

if you need more help you can bug nuckyz about it, he wrote that function and tbh i never used it

dull magnet
#

there's also jsdoc on the func that'll probably help

next stone
#

alright, thanks for the pointers, I'll see if I can figure it out :)

dull magnet
# next stone found this

basically the 5609 here is the id of the chunk that needs to be loaded and 336231 is the entry module id

#

so the function has you match those and then loads the chunk(s) and requires the module for you

next stone
#

right so I don't have to worry about 5609 myself right

#

the module that contains this snippet is 619326, that's the one I should be writing my finds for, yes?

#

just double checking

dull magnet
#

yes

next stone
#

I think the default regex might work for this snippet in particular

#

at least it looks like it

#

nevermind, appears I'll have to make one based on the one in pinDms since it looks similar

#

well, that seems to do it I suppose

dull magnet
#

can u just copy paste the one from that

#

it might work if you need just the settings too

#

it loads the colour swatches

#

actually yeah you just want the colour picker stuff right?

#

you can just copy paste allat from pinDms

next stone
#

right yeah

#

there's another one I need however, will figure it out

#

need the profile modal still

#

hah, and just like that we're back in action

#

coolio

dull magnet
#

neat blobcatnom

#

good job!

next stone
#

ah, yes, this again

#

@dull magnet I remember you giving me a solution to disable mouse interactions (setting pointer-events to none on a parent div), but that doesn't work

#

do you have any other wild guesses?

dull magnet
#

pretty sure events go from lowest element to highest

#

so it will prefer clicking the lowest element (in the tree)

next stone
#

though, adding !important also fixes it... leaSMUG

dull magnet
#

oh does it?

next stone
#

it was being overridden

dull magnet
#

ahh yeah okay so you also set it on all children makes sense

next stone
#

@dull magnet Updated the PR, could you check?

trail talon
#

does anyone know why this item isnt being patched to the context menu

#

also ignore the console logs and other stuff

#

ima remove that later

versed osprey
#

help would be very appreciated <3

stone crag
#

guys is dom manipulation acceptable if i want to render a component on top of everything else on discord

#

not sure where to patch

#

like createroot then render

#

like that

dull magnet
#

yes

stone crag
#

pog

flint bronze
cedar olive
#

that's so cool lmao

flint bronze
#

Is it ideal to patch over existing Store data to remove hidden embedded strings (like FakeProfileThemes' 3y3 system) or to remove them from wherever it's rendered?

#

If the former, how should I do that?

#

I'm planning to hide data inside channel topics

cedar olive
#

I dont understand what you want exactly

flint bronze
#

I would rather not have end users able to see the hidden 3y3-like data in my idea
If you're wondering what I'd use this data for, I want to build a way to replace the channel icons

cedar olive
cedar olive
flint bronze
cedar olive
#
- const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => () => {
+ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => {
flint bronze
#

it wouldn't be the same 3y3 format

cedar olive
#

oh

#

it depends honestly

#

but probably where it's rendered

#

do it first, fix the issue of those later

flint bronze
#

where even is channel topic rendered other than the obvious places

cedar olive
#

show hidden channels renders them

#

it uses the function of parseTopic or something

flint bronze
#

forum channels

cedar olive
#

those too

flint bronze
#

yeah thats what I mean

karmic marsh
#

i realized my mistake...

karmic marsh
#

ya'll know how to install a user plugin on vesktop?

whole cosmos
#

Not support channel + Dev install are not supported

karmic marsh
#

alr mb

whole cosmos
#

dw about it, just use the correct channel next time

balmy sky
flint bronze
#

that was easy blobhuskcozy

green vessel
honest stump
#

can I somehow render custom emojis without getting the emoji url and wrapping it in some random img tag

stable moss
#

I don't know the discord internal API well, but could we hook to any endpoint to check the unread/pings of the account switcher to display a little badge?

honest stump
stable moss
acoustic nest
#

Heck yeah my plugin was merged

acoustic nest
safe glade
#

I feel you

iron epoch
flint bronze
iron epoch
flint bronze
#

trust me, git was designed for feature branches

iron epoch
#

I am awful when it comes to isolation features

flint bronze
#

ok so heres how it works

#

basically when you want new plugin

#

you make new branch

#

do not branch off that unless you need to attempt modifications to that plugin

#

or you could go back and branch off older commits if you regret something

#

basically

#

branch for major changes to stuff

#

once you are happy with it

#

you merge into your actual branch with everything

iron epoch
#

so what you saying, that I should keep my plugins in separate branches and merge them when they are complete?

flint bronze
#

yes

iron epoch
#

I will make sure to remind myself when I use git next time. thanks

safe glade
#

git please be logical, do what I want for once

flint bronze
#

impossible

safe glade
#

-._.-

worthy frost
#

so i figured out adding buttons to messages pretty easily, but is there a way to only add a button on specific messages? like how the edit button only shows up on your own messages? or delete on messages you have permission to delete? (if sm1 responds, please ping me tyty)

dull magnet
#

you can return null

worthy frost
#

ty; 2nd question, is there a way to call async promises inside start()?

cedar olive
#

sure why not

worthy frost
#

ah i didnt realize i could just.. make it async lol

dull magnet
#

just make it not run too long

cyan rune
stable moss
cyan rune
#

I feel like constantly connecting and disconnecting whenever you open the account switcher may be seen as sus from discord's end? not sure about that though

#

if there is an endpoint I don't know about though, then it's probably somewhere in those docs

astral mantle
#

why not just stay connected the whole time to be able to receive notifications from other accounts?

#

honestly amazed that this is not a feature in discord already

cyan rune
#

that's an alternative

astral mantle
cyan rune
stable moss
stable moss
cyan rune
#

it sounds like an interesting idea tbh

cyan rune
#

seems like gateway is the only way to go, to my knowledge

dull magnet
#

you could maybe hijack their firebase (android push notifications)

cyan rune
#

that also works

stable moss
dull magnet
#

?

cyan rune
#

filter out any messages that don't mention you based on the message content (if it's not mentioning you, since you can enable notifications for all messages)

stable moss
# dull magnet ?

like, if you read the ping in your phone, it will take a while for firebase to push that event

#

also we cannot retro actively check back pings that were already there with gateway can we?

astral mantle
#

fun fact this one learned yesterday: firebase is based on xmpp

#

it's really cursed. android push notifications were originally literally just hooked up to google talk.

stable moss
#

(bcs it has no framming 💀 )

cyan rune
stable moss
cyan rune
#

I'm trying to figure out how the client even sees mentions in the first place

cyan rune
astral mantle
#

oh apparently the xmpp api is now finally deprecated

cyan rune
#

the gateway events page is pretty incomplete on discord.sex

dull magnet
#

probably via ready / ready_supplemental gateway event

#

you get them when you first connect

cyan rune
#

I'm reading the doc for that

stable moss
cyan rune
#

it doesn't mention mentions though

dull magnet
#

read_state on the ready event

#

check if it exists

#

you can enable gateway log in discord developer settings (use experiment plugin), and enable verbose log in devtools console

#

seems like the doc for ready event is incomplete

astral mantle
#

unrelated: is there a nice way to automatically apply a class like theme-midnight to <body> with vencord, to not have to copy-paste the official css from discord?

cyan rune
#

and holy shit this + party mode makes my client die

dull magnet
#

chrome devtools

cyan rune
#

ahhh

cyan rune
astral mantle
#

with a plugin

cyan rune
#

uncompress user plugin doesn't work on desktop wahoo

dull magnet
#

its right there

astral mantle
#

it is just a matter of document.body.classList.add("theme-midnight"), but where exactly to inject that (or an edit to the html maybe)

cyan rune
#

@stable moss there's your answer then ig

stable moss
stable moss
#

hmmmmmm, should i expend my weekend doing that

dull magnet
cyan rune
cyan rune
#

I do have to wonder if discord would find multiple gateway connections being created at once by user accounts too sus, but who knows

stable moss
#

the thing is, if we switch accounts constantly we would probably hit a ratelimit, bcs of reconecting too many gateways

#

is there a way to have a connection persist across account switches?

astral mantle
#

it's time to make a plugin to allow selecting the hidden darker and midnight (oled, kinda) themes nyaboom

cyan rune
astral mantle
#

it might be actually better to integrate it with the appearance ui, but it's not a huge deal if it starts off as its own thing ig

stable moss
cyan rune
#

was worth a try sob

astral mantle
#

actually can make sense too if you're one of those people™️ who use light mode sometimes

#

as this would only override your dark mode

stable moss
#

like we connect on startup, read the read_state and then just poll events from there

cyan rune
#

I'm not sure if modifying intents would be too sus but we could use that to remove some noise, like presence events

#

on that note what about presences

#

hmm

#

you could just send invisible for the default presence

stable moss
#

we can always use the new gateway reading app api 💀

cyan rune
#

the what?

stable moss
stable moss
cyan rune
#

oh my goodness

#

what the actual fuck

#

our privacy 📉

#

imagine authorising that

dull magnet
#

no you cant

cyan rune
#

it could literally read your messages lmao

dull magnet
#

and it doesnt affect privacy

cyan rune
#

unless they

#

huh

#

how's the implementation then

dull magnet
#

gateway connection != reading ur messages

#

there was always scope that allowed gateway connection

#

also fyi theres literally a messages.read scope lol

#

but the vast majority of scopes require discord approval

cyan rune
#

doesn't that

#

yeah I was about to say

#

and it's got something to do with local RPC iirc

#

they could make this gateway scope require approval tbh

dull magnet
#

anyway gateway connection isnt anything new

#

there was always
voice allows your app to connect to voice on user's behalf and see all the voice members - requires Discord approval

stable moss
cyan rune
#

that is only one part of gateway though, but tbf we don't know what the gateway scope will contain now or how it will be implemented

dull magnet
#

just gateway connection. nothing more

#

and it requires approval :p

cyan rune
dull magnet
#

no..

#

or maybe

#

but why does it matter

#

its discord approval only

cyan rune
#

true

acoustic nest
#

ok so

#

I unlocked the extra themes like midnight and darker

astral mantle
#

oh huh

acoustic nest
#

but when the client sends the API request to change the settings

#

the API just goes "yup, one dark mode coming up"

astral mantle
#

well, you can just apply theme-darker and theme-midnight class yourself ig?

acoustic nest
#

ye I suppose

#

I could probably overwrite the uh

#

onselect or whatever it is

#

but how do we persist that

#

if we do it like this

#

hm wait there were vencord settings right

#

a store I mean

#

seems so

bronze python
#

Hello, I'm trying to make a patch that replaces a function. the final goal would be replacing the code that updates (specifically) spotify's rich presence, but for now I'm only trying to make it log updates.
I checked that the find regex only matches one module from the devtools and that the match only matches once in the module with regex101.
I used the experiments plugin as a reference (along with the docs on github) to find my way around how to approach creating a patch and everything seems right, but nothing gets logged to console and the updates still behave as they did without the patch.
Here's my code:

export default definePlugin({
    name: "MusicTitleRPC",
    description: "Makes the song's title appear as the activity name when listening to music.",
    authors: [Devs.Blackilykat],
    start: start,
    stop: stop,
    patches: [
        {
            find: /"function .{1,2}\((?<e>.{1,2})\){let{connectionId:.{1,2},track:.{1,2}=\k<e>"/,
            replacement: [
                {
                    match: /"let{connectionId:.{1,2},track:.{1,2}=([^;]{1,2})"/,
                    replace: (e) => `$self.thingy(${e}); return`
                }
            ]
        }
    ],
    settings,

    thingy(e: any) {
        console.log(e);
    }
});
amber mantle
#

says it doesnt find anything for me,
u should utilize patch helper (pnpm watch) and vencord companion (vscode extension)
check pins

bronze python
amber mantle
#

well not required no

#

just mentioning it's existence

#

testing finds/patches without leaving ur editor might come in handy

bronze python
#

I'll give it a shot and see if it helps

cedar olive
#

you are gonna end up destroying the performance of your client startup in accident

#

look at every other plugin, they all use finds which are strings

bronze python
#

wouldn't i have to hardcode names then?

amber mantle
#

tbh i forgot u added regex finds Shake

cedar olive
#

yes but in a find you normally target text that does not change

#

regex finds are a last alternative for when a string find is not enough

bronze python
#

alright I'll change that to a shorter string

dull magnet
#

find a unique string in your module that isnt minified

#

for example in your module there's the string ContentInventoryManager"

bronze python
#

okay, got vscode and updated my find. Also I noticed I had /"regex"/ iinstead of /regex/ in my match, changing it now gives a SyntaxError:

Patch failed: Replacement 1 failed: SyntaxError: Unexpected strict mode reserved word

Here's the new code:

export default definePlugin({
    name: "MusicTitleRPC",
    description: "Makes the song's title appear as the activity name when listening to music.",
    authors: [Devs.Blackilykat],
    start: start,
    stop: stop,
    patches: [
        {
            find: "){let{connectionId:",
            replacement: [
                {
                    match: /let{connectionId:.{1,2},track:.{1,2}=([^;]{1,2})/,
                    replace: e => `$self.thingy(${e}); return`
                }
            ]
        }
    ],
    settings,

    thingy(e: any) {
        console.log(e);
    }
});
viral roost
bronze python
#

it's supposed to

bronze python
gentle marten
#

Can I edit the Clyde message that gets sent with sendBotMessage? I wanna use it as a sort of progress updater for an async task. Or is there a better way of giving progress updates?

viral roost
gentle marten
gentle marten
#

I'm downloading a video with yt-dlp

frosty otter
#

maybe an UI Component would be more fitting than repetitive bot messages

gentle marten
#

It shouldn't be too bad it fhere's only 1 message at any given time, and the message disappears once done

#

It's the result of a slash command, so it feels appropriate imo

frosty otter
#

maybe you could send a bot message after running the command and send a toast , when it is done

gentle marten
#

the problem is that while it is downloading, the command hangs. If the download takes a while, there's no clear feedback about whether it's working or not

#

I just want to show the user that something is actually happening

#

Coulb probably create a component that shows the loading state or something though

clear parcel
gentle marten
#

oh shit, thanks

#

Haven't used the dispatcher before but seems I'm not the first

bronze python
# bronze python okay, got vscode and updated my find. Also I noticed I had `/"regex"/` iinstead ...

I have now expanded the regex to actually replace the function (instead of having a return; in the middle)
My usage of the replace function in the patch seems to not work, when I hardcode condole.log(e) it patches OK but when I leave it to the capture group (as shown in the code below) it gives the same SyntaxError.

{
            find: "){let{connectionId:",
            replacement: [
                {
                    match: /let{connectionId:.{1,2},track:.{1,2}=([^;]{1,2});if\(null!=.{1,2}\)\(0,.{1,2}\.isEligibleForListenedMediaInventory\)\("ContentInventoryManager.handleSpotifyNewTrack"\)&&\(0,.{1,2}\.postTrackToContentInventory\)\(.{1,2},.{1,2}\)/,
                    replace: e => `console.log(${e})`
                }
            ]
        }
jagged briar
#

dont use .{1,2}, use \i

#

also use vencord patch helper

bronze python
#

Alright, updated to use \i and my issue was fixed by using $1 instead of the arrow function. Thanks everyone :)
Though I wonder, why does the experiments plugin use the arrow function when mine couldn't?

{
    match: /(?<=>)(\i)\.hasFlag\((\i\.\i)\.STAFF\)(?=})/,
    replace: (_, user, flags) => `$self.isStaff(${user},${flags})`
}
jagged briar
#

you dont have to use an arrow function for basic replacements

#

replace: "$self.isStaff($1,$2)

bronze python
#

that isn't my code, it's from the experiments pluign and my issue is fixed. I was wondering cause I took it as a reference

jagged briar
#

oh ok

cedar olive
#

it's a way to give a name to your capture groups

#

_ is the full match, user is the first capturing group, flags is the second

#

the same as $&, $1 and $2

bronze python
cedar olive
#

nono

#

$1 is your first capture group

#

here's a cheat sheet

bronze python
cedar olive
#

oh yeah

#

that's right

bronze python
#

ok cool ty!

cedar olive
#

the first argument is always the full match

stable moss
# cyan rune go ahead, it would be fun

Okay so the little that I have researched this has been:

I need to use the UserStore to get the current user id
Then I (optionally) need to use the MultiAccountStore to get info on the accounts
And use the tokens LocalStorage to get the auth for the gateway
Now only to look how to use the gateway

cedar olive
#

actually you need to use getToken("user id") to get the tokens

stable moss
cedar olive
#

findByProps("getToken")

stable moss
#

Okay thanks! Now I only need to figure out the gateway connection
And maybe how to persist it across account switching

#

but im pretty sure the second one gonna be impossible

cedar olive
#

hm I did find this

#

hm I guess not

#

pretty complicated stuff ngl

frosty otter
cedar olive
#

or create a new socket

frosty otter
#

that could also would

near aurora
#

@signal lichen

cedar olive
#

but you need to choose another compression method I think

stable moss
#

And I am trying to smash my head into how the find works

cedar olive
#

findByProps("setToken").getToken

#

if you dont know modules are like files that export things in javascript

node js

// a.js
export default function A() {}
export const B = 1;

...

import A, { B } from "a.js"

webpack or discord

// a.js
12345: (module, exports, webpackRequire) => {
  webpackRequire.setExports(exports, {
    setToken: function() {
      return setTokenDefinition;
    },
    getToken: function() {
      return getTokenDefinition;
    }
  })

  function setTokenDefinition() {
    blablabla
  }

  function getTokenDefinition() {
    dsdfdsfdf
  }
}

// b.js
34373: (module, exports, webpackRequire) => {
  const TokenUtils = webpackRequire("12345");

  function someFunction() {
     console.log(TokenUtils.getToken());
  }
}

// in a vencord plugin
const TokenUtils = findByProps("setToken");
console.log(TokenUtils.getToken());
stable moss
# cedar olive

Wait you can only have one GateWay connection per window?

cedar olive
stable moss
cedar olive
#

if you look here that's exactly what's happening

#

it's the way webpack bundles and makes modules work in browsers

stable moss
cedar olive
#

Find bad: Failed to find: Found more than one result! Make this filter more specific

#

this means more than one module exports a prop named getToken

#

which is true, another module exports getToken (it's the same function but whatever)

#

so instead I just changed your filter to setToken, since only one module exports that

#
function webpackRequire(moduleId) {
    var cachedModule = cache[moduleId];
    if (undefined !== cachedModule)
        return cachedModule.exports;

    var mod = cachedModule[moduleId] = {
        id: moduleId,
        loaded: false,
        exports: {}
    };

    return modules[moduleId].call(mod.exports, mod, mod.exports, webpackRequire),
    mod.loaded = true,
    mod.exports
}
#

this is the webpackRequire

stable moss
#

wait, so when we get by props lazy it doesnt get found till we use it?

cedar olive
#

yep

#

findByProps lazy only does the finding once you first try to use

#

so that we don't try to search before it was loaded and cached

#

it would fail if we did

stable moss
cedar olive
#

now you understand why :)

stable moss
#

Fun!

#

now only to wrestle with the gateway stuff

cedar olive
#

super unrelated but I have worked in something which changes the way we do the finding

#

it's no longer lazy

cedar olive
#

(the size of the cache, and this is not everything)

stable moss
#

It's clever

cedar olive
#

yes kinda

#

but it will not even try the cache if you use it properly

#

it will directly jump into wait for because nothing has been yet loaded

#

basically what wait for does is, it will check the filter when this happens

return modules[moduleId].call(mod.exports, mod, mod.exports, webpackRequire)

#

so as soon as it's loaded it will check if it's something we want

#

holy shit I just got a crazy idea

#

it's time to remove this :)

honest stump
cedar olive
#

this might actually work super well

#

:( shit

#

it uses the object directly

#

yeah can't run away from that nvm

#

hmmm wait I can try more cursed stuff

#

which is actually super interesting

#

time to cook

#

okay this is gonna be wild

#

no fucking way

#

this doesnt get called for object definitions

#

I am about to cry.

#

hm wait

#

:(

#

okay what I'm about to do is horrible but I just wanna experiment

#

you are not understanding.

honest stump
cedar olive
#

this is kinda working

#

wait wtf it worked?

#

lmaooooooooooooo

#

okay but this killed performance

#

this is the normal

#

if only I could intercept any value set... but I can't use a proxy here

cedar olive
#

BRO WTF

#

I FUCKING LOVE JAVASCRIPT

#

this language is insane

stable moss
worthy frost
#

what plugin might that be?

iron epoch
stable moss
#
class DiscordNotifier extends EventTarget

oh shit here we go again

honest stump
#

why are you writing like this husk?

jagged briar
#

wdym

stable moss
stable moss
dull magnet
#

you'd be much better off just making it an external app

#

then you can use a library dedicated for connecting to user accounts, like arikawa or discord.py-self and just send desktop notifications

#

which are designed to be safe for your account

stable moss
dull magnet
#

oh oki

#

just wanted to let u know so u dont put in extra effort just for it to not get merged anyway

dull magnet
safe glade
dull magnet
#

actually its a bot client so maybe their bot just got added to that by the person who owns that server

versed osprey
#

i finaly got the funny vencord badge :3

waxen shuttle
#

im trying to include the emoji picker in a modal, but the webpack module its in exports nothing else, so i have no idea how to get access to it (since the only way i know how to do that is findByPropsLazy and that doesn't work when there's only one export. anyone know how i might be able to do that?

dull magnet
#

a function thats default export?

#

findByCode

waxen shuttle
#

ah, ty

#

am i potentially misunderstanding how this function works? it cant find the module even when chrome devtools can.

dull magnet
#

it only finds exported members

#

if ur func isnt exported u cant find it

#

check what it exports

waxen shuttle
#

it.. doesn't seem to export anything in the source code, but i know it does since other modules import it. like it doesn't have one of these blocks of exported functions

dull magnet
#

it has to set default somewhere

waxen shuttle
#

seems to set it to a react thingy, can i search in that?

dull magnet
#

yes

waxen shuttle
#

i see

dull magnet
#

findComponentByCode

dull magnet
#
2345: (m, e, n) => {
#

that number is the module id

waxen shuttle
#

yea but doesnt that change when discord updates?

dull magnet
#

you can run wreq(2345) in console to import it (enable console shortcuts plugin)

waxen shuttle
#

ah okey

dull magnet
waxen shuttle
#

yeah i was trying to do that lol

#

ty for telling me how

#

ah it works, ty for the help

flint bronze
#

I need to access a really specific webpack module ( 277390 providing QRCodeWithOverlay )
I know it's used in the family center and login page
What's the best way to load it?

dull magnet
#

it's lazy loaded?

flint bronze
#

Yop

dull magnet
#

extractAndLoadChunk

#

i explained it to alyxia a few days ago how to use it

#

go looking for it

flint bronze
#

alright

honest stump
#

am i going insane or does MESSAGE_REACTION_ADD trigger on poll votes?

amber mantle
#

it indeed does

honest stump
amber mantle
#

me when emoji '2'

honest stump
#

i thought theres a separate event

#

i love discord

#

and the weird thing is i cant reproduce it half of the time

amber mantle
#

does that mean aliu reaction plugin detects poll votes

#

lmaoo

#

(it doesnt womp womp)

dull magnet
honest stump
#

most*

#

probably

#

idk

#

nevermind brainfart

bright barn
#

Hello, I'm trying to write a small plugin to hide blocked users from the user list.
I looked at noBlockedMessages, which removes blocked users' messages from the chat by patching Messages.BLOCKED_MESSAGES_HIDE
However I'm not sure what I should be patching. I tried UserList, Userlist, Users. But I am in the dark. Is there a list of these somewhere? "Messages" exists. What else exists?

#

Also: Maybe it's not possible to achieve through "patches", so if anyone knows any other plugin that modifies the user list, I can just look at that and probably get my answer.

astral mantle
#

MoreUserTags or PlatformIndicators maybe, though those just modify user entries rather than removing them

iron epoch
bright barn
#

Thanks folks, I will look into these three plugins and see what I can hack together. This is great.

#

(P.S why does blocking someone on Discord not hide them everywhere, anyway?)

proud parrotBOT
bright barn
#

looking at the code for export interface Patch I see it mention "module" being patched. So it seems like Messages is a module. And I am still wondering if there is a list of all possible such modules

iron epoch
bright barn
#

Thanks

bright barn
#

you seem to be right about renderRow

iron epoch
#

a protip: press { } to make code prettier and easier to read

#

||this is not from the vencord codebase, its discord code||

bright barn
#

search for that in the "components" tab of the developer tools?

iron epoch
#

you would find random js file name

bright barn
#

yes now I can search for it and find the js I can reverse engineer probably

bright barn
#

Presumably not everything can be patched in this way? This might be a fool's errand. Is there any way to know?

dull magnet
#

everything can be patched

bright barn
#

so it's just about finding the right one?
e.g. when I try to find: "renderRow" and click "Test Patch" in VS Code, I get 41 matches. Is it about narrowing that down to 1?

bright barn
#

The VS Code extension doesn't show the "Test Patch" shortcut when a regex is used, only for a string.
Is that just a limitation of the VS Code extension?

dull magnet
#

oh it doesnt support regex finds cause theyre very new

#

extension hasnt been updated

#

anyway dont use regex find

#

you dont need it in 99% of cases

bright barn
#

OK I figured it'd be something like that.

#

OK I will try without

#

If I search for the string renderRow:e=>{let t then I can narrow it down to 1. But t might change, presumably. In future.

iron epoch
#

then match something in renderRow after

#

it doesn't need to be exactly renderRow

bright barn
#

OK that's worth a try. If the VS Code extension says my plugin matches multiple "find"s does that mean the plugin will patch all of them? Or does it mean the plugin won't work?

#

I think I want to start by finding all of the renderRow definitions and replacing them with a function that returns immediately but does nothing

#

it's defined separately 8 times.

iron epoch
iron epoch
#

find something that could be unique

bright barn
bright barn
#

and learned a great deal, now my head is spinning

dull magnet
#

you only need to patch the one in question

bright barn
#

I know, rn I'm trying to:

  • Prove I can actually patch something by finding and replacing text (DONE)
  • Find the correct renderRow that is called when viewing members in the channel list
  • Find a string that lets me match that, and nothing else
  • Do the needful
bright barn
#

Hey I found it

#

I mean I'd rather the row was not an empty space but this is progress

#

maybe renderRow is the wrong thing after all. I will look again tomorrow

dull magnet
#

maybe

try to instead filter the data before it's fed into the component

flint bronze
cedar olive
#

you can try this

dull magnet
#

horror dont psoonfeed

cedar olive
#

find the module which you want to import from

dull magnet
#

oh

cedar olive
#

go up all the file til the .push statement

#

first argument (or second I dont remember) should be a number (as string), that's the chunk id

#

then search that id in the console and you will likely find where it's loaded

flint bronze
#

I already found that

#

in my case it's Promise.all([n.e("49237"), n.e("99387"), n.e("49368"), n.e("90688")]).then(n.bind(n, "978305"));

cedar olive
#

yep that's what you need

#

now you need a find for extractAndLoadChunks to find the module that has that

#

(thinking now it should support regex too but it's okay probably since I think the first argument is an array)

flint bronze
#

The code for it is ```js
568671: function(e, t, n) {
"use strict";
n.r(t),
n.d(t, {
default: function() {
return c
}
});
var a = n("735250");
n("470079");
var s = n("481060")
, l = n("626135")
, i = n("503899")
, r = n("292352")
, o = n("981631")
, u = n("689938")
, d = n("277886");
function c() {
return (0,
a.jsxs)(s.Button, {
innerClassName: d.qrCodeButtonContent,
size: s.Button.Sizes.LARGE,
onClick: ()=>{
(0,
s.openModalLazy)(async()=>{
let {default: e} = await Promise.all([n.e("49237"), n.e("99387"), n.e("49368"), n.e("90688")]).then(n.bind(n, "978305"));
return t=>(0,
a.jsx)(e, {
...t
})
}
),
l.default.track(o.AnalyticEvents.FAMILY_CENTER_ACTION, {
action: r.FamilyCenterAction.ShowQRCodeModal
})
}
,
children: [(0,
a.jsx)(i.default, {}), u.default.Messages.FAMILY_CENTER_REQUESTS_LINKING_BANNER_TEEN_BUTTON]
})
}
},

#

I GOT IT

#

I think

#

ok time to get 429 too many requests on /users/@me/invites endpoint

flint bronze
#

okay I kinda have some hacky mess working

#

now I wanna unfuck my other hacky mess

#

This is very awful.

cedar olive
#

instead of exporting just set it in the object of your plugin

#

$self.blabla = $3

flint bronze
#

Yeah I kinda did that

#

Is a setter a stupid way of doing it

cedar olive
#

if you need to use outside the plugin object no

flint bronze
#

oh also

#

i am curious

#

did discord bomb friend finder endpoint

#

In case anyone was wondering what I'm building, it's a UI for the friend invites plugin

#

or do you need to opt in from the mobile app to enable contacts to add me

cedar olive
#

ask the alien friend

flint bronze
#

i already checked @clear parcel site for it

#

no docs for it

#

only specifies the code field in createFriendInvite

dull magnet
#

one of them broke

#

the other still works

#

iirc

flint bronze
dull magnet
#

it's been that way for months

flint bronze
flint bronze
# flint bronze

@gritty sparrow can you explain how that code even worked in the first place and what all those fields mean
I see a lot of 1 but I do not know what I need to tweak to get a custom max uses value to be registered or even if it's possible anymore

#

i wouldnt be surprised if discord bombed it

#

WE aliening NO DOCUMENTATION

#

WE aliening DEPRECIATED FEATURES

clear parcel
#

ya iirc that first ep is gone for good

flint bronze
#

they bombed it

#

guh

clear parcel
#

ignore all the fields, use the ep in the else block

flint bronze
#

are you saying i will have to stick with 5 max uses 1 week validity

clear parcel
#

most likely

flint bronze
#

guh

clear parcel
#

I can maybe check it out

#

?remind 23h

#

:remind 23h

#

!remind 23h

#

;remind 23h

#

vencore got no good bots

#

someone ping me in 23h thx

flint bronze
#

why 23 hours specifically

dull magnet
clear parcel
#

sounds good

dull magnet
#

there's pissbot

clear parcel
dull magnet
#

ve setTimeout(() => channel.createMessage({ content: "pookie @eager abyss", allowedMentions: { users: ["1026534353167208489"]}}), 23 * HOURS_IN_MS)

shrewd tundraBOT
dull magnet
#

wait what

#

unknown user

clear parcel
#

real

dull magnet
#

😨

clear parcel
#

not my id

#

idk what you copied lol

dull magnet
#

the hell did i copy

clear parcel
#

role id?

dull magnet
#

oh yeah it's contributor role lmaooo

#

idk how tf i copied that

clear parcel
#

right click on role in member popout

flint bronze
#

you should be glad there is @ and @&

clear parcel
flint bronze
#

else you would've just pinged 200 people

dull magnet
#

i added rdanner

#

?remind 17y what's good boomer

fathom pivotBOT
#

Alright @dull magnet, in 17 years: what's good boomer

dull magnet
#

gonna be almost 40 then wtf

jagged briar
#

is there a specific way to make this menu or do i have to find it myself

#

(ping reply please)

jagged briar
#

i found the module but idk how to get it in code, this doesnt find anything
const PickerTab = findComponentByCode(".AnalyticEvents.EXPRESSION_PICKER_TAB_CLICKED");

cedar olive
#

thea actual export is in the middle of the module

#

t.default = r.memo(...)

clear parcel
#

?remind 18h

fathom pivotBOT
#

Alright @clear parcel, in 18 hours: …

jagged briar
iron epoch
waxen shuttle
#

hey y'all, would it be bad to edit utils.ts in a plugin pull request? i had to access the module to add reactions to messages and i feel it might be useful to other plugins but idk what i should do and i feel like asking is probably my best course of action

jagged briar
amber mantle
#

then realized u can resize horizontally without plugin

jagged briar
#

no im making a plugin like FavoriteAnything but better

#

with folders and stuff

amber mantle
#

ah

#

leech gifcollection trolleyzoom

clear parcel
#

too bad the gif picker is slow now that they added ?params and caching is broken

jagged briar
fathom pivotBOT
#

@clear parcel, <t:1716351559:R>: …

fathom pivotBOT
#

@clear parcel, <t:1716416380:R>: …

clear parcel
#

fiiine

shrewd tundraBOT
#

pookie @eager abyss

dull magnet
#

lmaooo

dull magnet
clear parcel
jagged briar
#

it compiles fine so i think my vscode is being stupiud

dull magnet
#

(build does no type checking)

jagged briar
#

does anyone know what this object does (it is required to use expression picker functions like opening it)

#

this is the module that generated it

#

how would i even find this module

dull magnet
#

that module is def not what u need lol

#
const { ChatInputTypes } = findByPropsLazy("ChatInputTypes")
#

its just config for the slate input

#

customises behaviour depending on which context youre in

jagged briar
#

thank you

clear parcel
#

friend finder appears neutered and there's no other way to make the 1 use invs

#

idk why they didn't expose max_ params on the ep

iron epoch
# jagged briar stealing your api rn

yeah sure, but make sure to take the one from the TablistApi branch as the one in the fun branch is not maintained anymore (there isn't many changes externally other then the names of functions/components)

jagged briar
#

too late

#

it works really well though

jagged briar
#

i have these two finds that don't work on the top level, but they do work when the find is executed in start. should i just leave them in start or is there something im doing wrong?

dull magnet
#

remove .NORMAL

#

bottom one should work

jagged briar
#

oh i thought the bottom one was broken too but yeah that works

#

how does that work though, just removing a property access causes it to work?

dull magnet
#

you can't immediately access inner properties

#

that makes it non lazy

jagged briar
#

ah got it

dull magnet
#

you can only access exports

cedar olive
#

but the reason the first property access work is because we make those lazy too, in case you do what you are doing there

flint bronze
#

discord so stupid for not adding

cobalt radish
#

I used to use BetterDiscord and there was a plugin that added some features to images, one of the features was displaying the file name and size below images. Is there a plugin that already does that? I'm considering making it if there isn't.

frosty otter
#

There already is a plugin request for that and from my knowing it is also being developed by someone already

astral mantle
#

for MessageLatency, i wonder if it would be worth implementing edge cases like "this message seems to have a delay of 5 minutes, but they replied to a message newer than that, so the actual potential delay is lower than that and their clock is probably just off"

sand ember
#

is there any point in developing complex algorithms just to tell you that some random user's clock is 2 min wrong?

astral mantle
#

i wouldn't really call it a "complex algorithm", it's a simple comparison

#

but tbh, it is probably unnecessary, and instead the general message could be changed to something like "This message was sent with a delay of X (or their clock is off)."

jagged briar
#

I’ve sent a message and then it says that my clock is 2 seconds behind

opal fern
#

I heard from the grapevine that using APIs you host yourself isnt going to get merged into the main repo... Is there a way to get the server "officially hosted" so that I can have my plugin merged?

astral mantle
#

(i didn't change anything)

dull magnet
honest stump
jovial field
#

i'm currently developing a new plugin and am trying to put a select dropdown next to the display name input field in the profile settings tab
i've tried a similar approach to the 3y3 button

addStyleSelector: ErrorBoundary.wrap(function ({ pendingGlobalName }: { pendingGlobalName: string; }) {
    return <Select
        placeholder="default"
        options={styleOptions}
        select={(font: string) => stylizeName(pendingGlobalName, font)}
        isSelected={function (value: any): boolean {
            throw new Error("Function not implemented.");
        }}
        serialize={function (value: any): string {
            throw new Error("Function not implemented.");
        }}>
        Style your Display Name
    </Select>;
}, { noop: true }),

but my patch errors (unexpected token '.'),,, i am certain i've found the right place to patch in

{
    find: ".DISPLAY_NAME_MAX_LENGTH",
    replacement: {
        match: /(\i)\.currentGlobalName\)&&void\s*0!==(\i)\?(\i):""}\)/,
        replace: "$&,$self.styleSelector($1.pendingGlobalName)"
    }
}

i feel kinda stuck, are there any obvious mistakes here i haven't caught on to?
edit: the patch is supposed to append my component after the TextInput field where Display Name is changed

dull magnet
#

use patch helper to see the diff

#

or look at the error in the devtools

jovial field
#

when you realize you renamed a function but forgot to update it elsewhere content

jagged briar
#

What's the best way to get the file type of a file? I don't want to just check the extension and making a request would require a native.ts for cors and that seems really unnecessary

export async function getMediaType(src: string): Promise<MediaType> {
    return await fetch(src, {
        method: "HEAD",
        mode: "no-cors"
    }).then(res => {
        const type = res.headers.get("Content-Type");
        if (type?.startsWith("image")) return "image";
        if (type?.startsWith("video")) return "video";
        if (type?.startsWith("audio")) return "audio";
        return "image";
    });
}
iron epoch
#

I don't see cases where this could go wrong other being undefined

jagged briar
#

No adding no-cors makes the response opaque so there is no headers

jagged briar
#

It isn’t

#

No headers are available when I did it

dull magnet
#

no

#

nothing is

jagged briar
#

So I can choose what component to render based on what file type it is

jagged briar
#

got it working with a native.ts but i feel like its a bit unnecessary, is there a different solution?

dull magnet
#

describe the full use case

#

different component based on file type? wha?

#

how is that useful if you can't fetch the file anyway

iron epoch
#

and are we talking about someone sending a url and check what's the file type in that or just some regular discord attachments?

jagged briar
#

im making a place to store media in discord, like the favorite gifs but with any media. i want to display the media, and i need to know what kind of media it is to know how to render it, like a video, image, or audio. for some reason, making a fetch request for it requires you to go through cors but putting it in a video or image tag does not.

iron epoch
#

to avoid fetching?

jagged briar
#

that's what im going to do but i still need to get the type somehow

#

i might be able to get it from the message itself

iron epoch
jagged briar
#

yeah didnt think about that

#

yuppers

iron epoch
#

ah the message

#

if only I wasn't in incognito mode

flint bronze
balmy sky
#

How can i make an input field component that's styled like a discord codeblock?

#

There might be a plugin that has already done this but i can't think of one off the top of my head

flint bronze
astral mantle
balmy sky
#

I'm not sure how to get it to look right though

astral mantle
#

idk, not on a computer rn to check, probably just a matter of applying the appropriate class(es)

meager palm
#

i want to make a vencord plugin, where can i start? im lost because there arent any documentations anywhere and the plugin-template is archived lol

woven lion
#

though it should be relevant enough

#

plugin-template is from an experimental plugin loader that never got implemented into vencord, so dont worry about it

#

the only supported plugin type is the one thats built in

#

oh yes

#

the vscode extension is a helper that lets you test patches from vscode itself to make sure they're valid

#

its quite handy

small pine
#

does anyone know why when i try to create an iframe it responds with "Refused to frame because it violates the following Content Security Policy directive"

#

it does this with any url in discord, but it allows me to create the iframe on a different site which means it isnt the url problem

normal oriole
#

Just a wild guess: because of the content security policy husk

flint bronze
#

yeah

#

read the error blobcatcozy

#

theres probably some way to bypass it

#

iirc vencord already has to somehow

#

yeah

#

read src/main/main.ts

small pine
#

alright

small pine
flint bronze
#

No

#

It adds more trusted sources

small pine
flint bronze
#

what is this iframe you are trying to load anyway?

small pine
#

just a document embed

flint bronze
#

add frame-src to the automatic directive injection thing

small pine
#

thank you, it worked

balmy sky
#

I'm having a weird issue, i'm trying to hyperlink to another site in a plugins about component but it throws an error when pressed

#

(vesktop and plasma x11 if it matters)

dull magnet
#

what's ur code

#

are you maybe forgetting target="_blank"

balmy sky
#

Oh yop it works now

#

Thanks

iron epoch
balmy sky
#

How do i get the users favourite gifs? i tried looking at the stores but nothing useful seemingly (also can't think of any other plugins that go this)

dull magnet
#

UserSettingsActionCreators.FrecencyUserSettingsActionCreators.getCurrentValue()

#

should be that

flint bronze
#

Why are you actually making GifRoulette

#

Insane

balmy sky
flint bronze
#

You will get caught posting NSFW in general chat and enjoy ban

#

(jk)

amber mantle
#

that will actually happen

#

trol

flint bronze
#

yop

slender barn
#

why did nobody tell me to use native.ts lol

#

I'll try that and see if it works

jagged briar
#

how tf am i supposed to match this

viral roost
#

match something else in the module probably

jagged briar
#

its for a find

#

module is 215016

#

ok i got it

slender barn
#

my plugin is fixed

amber basin
#

help i forgot react basics

#

its being used in a function component

dull magnet
#

then call it like $self.MemberListBanner({ user: ... })

amber basin
#

got this far, now need to go through the queue

dull magnet
#

oh do you not yet?

#

you can just use the queue util in vencord

#

it makes it super easy to do promises sequentially

#
import { Queue } from "@util/Queue";

const queue = new Queue();

queue.push(() => doStuff());
queue.push(() => doOtherStuff());
amber basin
#

oh shit ty

#

how do i tell userProfileStore to fetch the profile

#

getUserProfile returns whats in the store

#

oh thats in util

#

its infinitely fetching profiles down the list, its not restricting itself to just viewport?

#

oh wait it stops like 200px down

#

okay

dull magnet
#

useStateFromStores subscribes to store changes

amber basin
#

i got it

dull magnet
#

if you read the fetchProfile() function code you will see that it dispatches flux events USER_PROFILE_FETCH_SUCCESS, GUILD_MEMBER_PROFILE_UPDATE, etc

#

the profile store is subbed to these events

#

so whenever that event is dispatched, the store will handle the event, then the store will call its own change listeners

#

whcih will in turn trigger your state to be updated

#

so all you need to do is

  1. sub to the store via useStateFromStores
  2. fetch the profile if necessary
amber basin
#

yeah it works

dull magnet
#

discord's store + event system is really awesome

#

super cozy

amber basin
#

oooooo

cedar olive
#

@dull magnet btw, super random, but I looked more into message updater api in the past, I was able to manually dispatch store updates

#

however, messages are also memoed

#

so they were not getting updated because of that

green vessel
#

I'm trying to make a plugin that when running a slash command it will send an embed of a random photo from my GET api, although when I run the command it just displays the link instead of the photo. I have no clue how to fix it and neither did my friend.

        {
            name: "raccoon",
            description: "Gets a random raccoon image.",
            inputType: ApplicationCommandInputType.BUILT_IN,
            execute: async (_, ctx) => {
                const data = await fetch("https://api.racc.lol/v1/raccoon?json=true")
                    .then(response => response.json())
                    .catch(err => {
                        console.log(err);
                        sendBotMessage(ctx.channel.id, { content: "There was an error. Check the console for more info" });
                        return null;
                    });

                if (!data) return;

                let imageUrl = data.data.url;
                imageUrl.replace("http", "https");

                sendBotMessage(ctx.channel.id, {
                    embeds: [
                        {
                            type: "rich",
                            title: "Random Raccoon",
                            color: 0x8663BE,
                            description: `${imageUrl}`,
                            image: { url: imageUrl },
                            footer: {
                                text: "using racc.lol",
                            },
                        }
                    ] as any
                });
            }
        }
    ]```
jagged briar
#

Check the network tab to see why the request is failing cause that’s most likely why it won’t show up

dull magnet
amber basin
#

yeahhh fear

#

i tried to merge dev into it

#

and git didnt like that

dull magnet
#

in the future just use this button lmaooo

amber basin
#

oh

dull magnet
#

or git merge upstream/dev

#

did u do a rebase

#

bad idea

green vessel
amber basin
#

i just do this with gitlens

safe glade
#

vee checking their income

dull magnet
#

you're better off making a user installable app

green vessel
#

🔥

amber mantle
#

selfapp NODDERS

safe glade
#

selfapp (like pinging mantikafasi)

dull magnet
#

doesnt require a client mod and is way more useful

#

user installable apps are really cool

green vessel
#

Tried making a plugin and got shit on lmao

dull magnet
#

wdym shit on 😟

#

im not meaning to shit on u, just saying that your idea is better off as a regular bot

dull magnet
# dull magnet

cause u can do this and it'll work even on mobile and anyone can install ur bot and use its commands globally on discord

green vessel
#

User apps aren't out yet iirc

dull magnet
#

they are!

#

just beta

#

they're gonna be stable soonish

green vessel
#

Is there docs? Or do they just work like bots

dull magnet
dull magnet
green vessel
#

Well that answered my question

flint bronze
#

for some random plugin i make

delicate totem
#

anyone have any idea why this wouldn't work?
function at the bottom just doesn't properly update the status (it just duplicates it for some reason but also doesn't show for anyone other than myself)

north flame
#

Hey uh, Vee told me to replace tsx { find: "Messages.ROLE_ICON_ALT_TEXT", replacement: { match: /function\s+\w+?\(\w+?\)\s*{let\s+\w+?,\s*{className:.+}\)}/, replace: "$self.RoleIconComponent=$&;$&", } }
with findComponentByCode. Could anybody give me some pointers on how that works?

#

nvm, figured it out lol

#

looked more complicated than it was

balmy sky
#

Is there no enum application command option type? i think i might be blind

iron epoch
balmy sky
#

I wouldn't be surprised if there is

jagged briar
#

finally got rendering the tab working

safe glade
#

get rotated

iron epoch
# jagged briar yay

looking great, and aw cute cats you got there.
one question does the search work?

jagged briar
#

nop

#

still havent gotten around to implementing it

iron epoch
#

lemme send it

jagged briar
#

i plan on allowing you to add a description to your media and making the search use that or the url if there isnt one

#

and it will also use fuzzy search

iron epoch
jagged briar
#

wreq(parseInt(findModuleId("useExpressionPickerStore:") || "0")); husk