#🧩-plugin-development
1 messages · Page 64 of 1
Ideally you don’t add dependencies for a plugin
What is your plugin and what is the dependency
SpotifyControls, I'm trying to use the SpotifyStore
I'm trying to get the album art of the song playing, get the most prominent color from it then set it as a theme or set the secondary background of discord as the color
just import the store
Noobie question. I'm getting the following error when trying to access someone's Display name. This is an excerpt of what I'm trying to do
Property 'globalName' does not exist on type 'User'.
import { Message } from "discord-types/general";
let recentmessage: Message;
// ...
console.log(recentmessage.author);
const displayName: string = recentmessage.author.globalName;```
When checking with a console.log, I notice that field actually does exist, which is weird. But sometimes it also evals to null.
depends on, if the user has set an nickname for the server
Oh so globalName == server nickname? How do I get the display name? Is that possible
afaik it depends, on how you are fetching the user
are you just getting it from the author attribute from a message?
yes I think so
i tried "@webpack/common" to no avail
import from webpack not react
like this
nvm im dumb
discord-types is really outdated
just ignore the error
multiple plugins already do that
multiple plugins fetch the display name, or ignore the error?
Is there a more modern/better way or do I just have to add a fallback for null cases
globalName == whatever name shows up in the current server right¿
migrating a db from someone who hates the world to my stuff (thank god its on github) feels amazing
Both
You can just type the user as any
nop
// @ts-expect-error discord-types is outdated
place that comment the line before it
does anyone know if it's possible to use a patch to change the status icon SVG? I could only find the SVG for each respective status icon getting called twice, and changing it seems to do nothing
you can do it with css
see I tried doing that, but changing your own status seems to scrape the status icons on your profile of the color and svg attributes, so changing your own status will override your own status icon to the default SVG, and the attributes only seem to reappear for your status icons when the element that contains your status icon is refreshed (like closing and opening members tab or changing channels)
@dull magnet
I cant figure out how to patch wreq.f.css
for some reason patchHelper can't ever find it?
otherwise how did you intend for me to hook into it with this comment
https://github.com/Vendicated/Vencord/pull/2662#discussion_r1666961976
you can't regex patch the webpack loader
how did you intend for me to hook into it then?
this currently sounds like "you should do this. also doing 'this' is impossible"
🐵 🩹
How tf
findByProps('prop') = () => { return PATCHED_VALUE }
but the property needs to be exported
there also is
findByCode and stuff
findByCode('ChunkLoadError') // => null
-# yes so please don't suggest things that you know don't work
meow
it's wreq.f.css
just said, how to monkeypatch, not what would work in your specific use case
please point me to a single example of safe monkey patching in vencord and I will implement
Vee going from whatever the numbers that spits out to /assets/[...].css is an extraordinary pain in the ass and more husk than a mutationObserver will ever be
false
what on earth are the validations happening above that though
or even read source code
https://github.com/web-infra-dev/rspack/blob/ebcd2774d5641fd17f6ed4b7ea783d930de2e7c1/crates/rspack_plugin_css/src/runtime/css_loading_with_loading.js#L1
https://github.com/web-infra-dev/rspack/blob/ebcd2774d5641fd17f6ed4b7ea783d930de2e7c1/crates/rspack_plugin_css/src/runtime/css_loading_with_loading.js#L21
css_loading_with_loading.js: Line 1
__webpack_require__.f.css = function (chunkId, promises, fetchPriority) {
css_loading_with_loading.js: Line 21
var url = __webpack_require__.p + __webpack_require__.k(chunkId);
this is what I mean by you knowing what is going on
I had no idea what I was even looking at
you can also refer to this if you want
every prop of wreq documented
it explains what wreq.k is
and wreq.f.css
your attitude isn't helping though
less "this is too hard", more "how do i do this"
you'll get much further in life
lmaoo grammar
sorry I currently can't think of any clean code that does what you want
a useful tool is https://grep.app
whenever you see code in Discord that belongs to an open source library, just search some keywords and you'll quickly find source code https://grep.app/search?q=.f.css
Search across a half million git repos. Search by regular expression.
thanks
try to start doing it and ask for help if you cant progress
I will help you if you need
okay
I would like to implement in a way that can be used by multiple components, so I am thinking of implementing like
cssUtil.ts
export const newStyleListeners: [(styles: string) => void] = [];
const orig = wreq.f.css
wreq.f.css = function() {
// call each listener in newStyleListeners with the result css
// point to orig
}
Then plugins can opt in with
start() {
newStyleListeners.push((styles) => {
...
})
}
but a mutationobserver would probably also be okay
as long as u only watch head
and do it proerpyl
is there anything wrong with current implementation then?
it's honestly pretty easy to do with wreq.f.css though
because it does only watch head currently
send me your current implementation with observer
cssUtil.ts: Lines 17-30
export function newStyleListener(callback: (styles: string) => void) {
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (!(node instanceof HTMLLinkElement) || node.rel !== "stylesheet")
continue;
parseStyleLinkNode(node).then(callback);
}
}
});
observer.observe(document.head, { childList: true });
}
okay one second
n.f.css = function(t, r) {
var a = n.o(e, t) ? e[t] : void 0;
How do I get installedChunks or e in a monkeyPatch context?
css_loading_with_loading.js: Lines 1-5
__webpack_require__.f.css = function (chunkId, promises, fetchPriority) {
// css chunk loading
var installedChunkData = __webpack_require__.o(installedChunks, chunkId)
? installedChunks[chunkId]
: undefined;
without this check, I would be calling the listeners every time a new chunk is added, even if that chunk has already been added to the app
not an issue though since it's unlikely a chunk will get asked to be loaded more than once
pretty sure
let me just cook a way for a plugin to easily access wreq when it's loaded into vencord though
time for wreq listeners
false xd
whenevr u change channels
discord loads these
it was a guess honestly xd
however I think the way you are gonna do this is using the return value the promises argument of wreq.f.css
you can probably differ when a chunk is loading/loaded using it
wreq.f.css doesn't return anything?
or am I misinterperet 
promises seems like its always empty for me
yes cuz all of those are already loaded
cssFunc = wreq.f.css
wreq.f.css = function(chunkId, promises, fetchPriority) {
cssFunc.apply(this, [chunkId, promises, fetchPriority])
if (promises.length === 0) return
console.log(promises)
}
oh this works and is promising
I get you
use .call, not .apply
yes, it uses apply cause it has args as an array :p
.callwhen you have multiple arguments.applywhen you have an arguments array
ahh
when a css is chunk is being loaded it returns a promise
that resolves when it's style tag is loaded
eh
mutation observer might be cleaner
I have been screwing with variations of this trying to get it to just say each chunk id once with no repitionion and I can't figure out something neat
yea
you already have to do all of this just to monkey patch wreq.f.css as soon as possible
then you would have to see if promises is not empty
wait for all of them to resolve
obtain the full css path with wreq.p + wreq.k
fetch it and do all the blabla
and beforeInitListeners isn't even a thing anymore in future versions which means I would have to re-add a variation of it

false
function onWreqDefined(wreq: any) {
onceDefined(wreq.f, "css", () => {
const orig = wreq.f.css;
wreq.f.css = function () {}
})
}
I have spent 2 hours screwing with wreq.f.css and my brain hurts

even then it's being called twice
evil
doesnt handle the calling twice but yeah
vomit
const idsSeen = new Set():
https://tenor.com/view/mercy-overwatch-come-here-gif-14280244
yep yep ik
const chunksLoading = new Set<string>();
function onWreqDefined(wreq: any) {
beforeInitListeners.delete(onWreqDefined);
onceDefined(wreq.f, "css", () => {
const handleChunkCss = wreq.f.css;
wreq.f.css = function (this: unknown) {
const result = Reflect.apply(handleChunkCss, this, arguments);
if (chunksLoading.has(arguments[0])) {
return result;
}
chunksLoading.add(arguments[0]);
if (Array.isArray(arguments[1]) && arguments[1].length > 0) {
(async () => {
await Promise.all(arguments[1]);
chunksLoading.delete(arguments[0]);
console.log("css chunk", arguments[0], "loaded");
const cssFilepath = wreq.p + wreq.k(arguments[0]);
const css = await fetch(cssFilepath).then(res => res.text());
console.log(css);
})().catch(() => { });
}
return result;
};
});
}
beforeInitListeners.add(onWreqDefined);
¯_(ツ)_/¯
that doesn't account for the initial css though
the base one
neither does mutation observer
yikes
// returns all of discord's native styles in a single string
// ! discord lazy loads css chunks, make sure to use newStyleListener as well
export async function getStyles(): Promise<string> {
const out = "";
const styleLinkNodes: NodeListOf<HTMLLinkElement> = document.querySelectorAll('link[rel="stylesheet"]');
return Promise.all(Array.from(styleLinkNodes, n => parseStyleLinkNode(n)))
.then(contents => contents.join("\n"));
}
// runs callback with styles of new style nodes added to the head
export function newStyleListener(callback: (styles: string) => void) {
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (!(node instanceof HTMLLinkElement) || node.rel !== "stylesheet")
continue;
parseStyleLinkNode(node).then(callback);
}
}
});
observer.observe(document.head, { childList: true });
}
async function parseStyleLinkNode(node: HTMLLinkElement): Promise<string> {
const link = node.getAttribute("href");
if (!link) return "";
return fetch(link)
.then(res => res.text())
.catch(() => "");
}
Feels nicer and has the inital css
it should if you run it earlier
like outside of your start()
iirc that is forbidden
well yeah but you cant have a start at init and a start at domcontentloaded at the same time
why don't I just start at init then?
then we listen and develop css as stuff loads
yeah
I will rewrite based on that then
How do I import SpotifyStore in to my plugin? I tried doing
const store = await SpotifyStore;
then accessing the values stored but it always returns undefined or null
How are you defining or importing SpotifyStore?
that await does nothing idk what you're expecting it to do
but yes show full code
how would I replace this code? its the code that defines the masks for icons, I'm trying to replace them with custom masks
(s = "svg-mask-status-idle",
(0, a.jsxs)("mask", {
id: s,
maskContentUnits: "objectBoundingBox",
viewBox: "0 0 1 1",
children: [
(0, a.jsx)("circle", {
fill: "white",
cx: .5,
cy: .5,
r: .5
}),
(0, a.jsx)("circle", {
fill: "black",
cx: .25,
cy: .25,
r: .375
})
]
}))
tried this but it doesn't seem to work, so I'm probably doing something wrong:
patches: [
{
find: /s\s*=\s*"svg-mask-status-idle"/,
replacement: {
match: /s\s*=\s*"svg-mask-status-idle"/,
replace: `
(s = "svg-mask-status-idle",
(0, a.jsxs)("mask", {
id: s,
maskContentUnits: "objectBoundingBox",
viewBox: "0 0 1 1",
children: [
(0, a.jsx)("path", {
fill: "white",
d: "M 0.5 0 C 0.224 0 0 0.224 0 0.5 C 0 0.776 0.224 1 0.5 1 C 0.776 1 1 0.776 1 0.5 C 1 0.224 0.776 0 0.5 0 M 0.125 0.5 C 0.125 0.293 0.293 0.125 0.5 0.125 C 0.707 0.125 0.875 0.293 0.875 0.5 C 0.875 0.707 0.707 0.875 0.5 0.875 C 0.293 0.875 0.125 0.707 0.125 0.5"
}),
(0, a.jsx)("circle", {
fill: "white",
cx: 0.5,
cy: 0.5,
r: 0.2
})
]
}))`
}
},
Just do that with css
isn't patching be more reliable tho?
Wait I don't know if you can use css to replace a circle with a path
But you're doing (at least) two things wrong here
You're replacing (s="svg-mask-status-idle",original svg) with ((s="svg-mask-status-idle",custom svg),original svg) which just doesn't do anything
And you're hardcoding the minified variable names, meaning it'll break within 48 hours
A better patch would be something like match: /"svg-mask-status-idle",/, replace: "$&$self.IdleIcon??"
That is
Definitely a patch
oh I didn't even know that's a thing
I probably should've read the patcher cheat sheet lol
thanks, I'll try that
currently just trying to figure out how to make match: /"svg-mask-status-idle",/ more specific because patcher shows its matching the wrong thing
/\i="svg-mask-status-idle",(?=\(0,\i.jsxs\))/ perhaps
the closest you'll get to that is the background overlay option
didnt see that
That's a similar style but not the same
its just barely different and its annoying me
im using the red text but it doesn't currently work well for Subtext, Mentions, Codeblocks and Spoilers.
red background should be default imo cause you can actually tell if a message with just an image was deleted
Imo default should be red background plus folding
oh nvm theyre back
there was a time when favourite gifs didn't sync
So i'm trying to make a plugin that saves channel drafts across sessions, my first idea is to save the draftstore data in the datastore on stop and load it on start. Does the draftstore have the functions for that? From what i can see there isn't a get all/set all function
Stores.DraftStore.getState()
but it already saves
to localStorage
it extends PersistedStore
which persists to localStorage
Oh it sorta works now
async start()
{
const getData = await DataStore.get(dataStoreKey);
if(!getData) return;
localStorage.setItem("DraftStore", getData);
DataStore.del(dataStoreKey);
},
async stop()
{
await DataStore.set(dataStoreKey, JSON.stringify(DraftStore.getState()));
}
wdym by session
Sorry, I mean if you type something in a channel (don't press send) and close/restart your client the draft disappears
@balmy sky your discord is broken, drafts persist for me
Am I fucking tweaking
just doing
import { SpotifyStore } from "plugins/spotifyControls/SpotifyStore";
then accessing the values like so:
const store = SpotifyStore;
const track: Track = store?.track;
then track would return as null or undefined
I'm gonna go insane, I found a way to do it, but mobile icon SVG replacement doesn't seem to work and I think it's because Dicord doesn't have specific code for online and online-mobile
I'll try finding a workaround in the morning, I'm so tired I'll gonna be knocked out the minute I hit the hay
why are you working with mobile 
the mobile status icon that shows up when someone is on mobile
oh, im really stupid
what is an ErrorBoundary
Component to prevent the entire site from crashing if an component fails to render and display the error
ah, makes sense
you can just search for ErrorBoundary in vencord src to see, how to use it
Basically the react version of try/catch
Displaying Icons based on Permissions
is anyone else's discord canary installation fucked up rn? (Getting a popup that "Environment variables are not set." or the discord app just not loading at all.)
(Auto-response invoked by @dull magnet)
venbotto i was just asking
I wish native could directly print stuff to console
it can
there is nothing stopping you from printing to stdout with console in native
and theres nothing stopping you from calling a native function from renderer to get the webcontents and use executejavascript to send to logs there
probably a better way of doing this btw
is it possible to make two patches depend on eachother
They must be within the same find (same module)
replacement can be an array of replacements
set group to true for patches to not apply if one fails, useful if depending on another patch in the same module (for variables)
this is what i needed, ty
(this is the way to do it) if your desire is for native logs to show up in renderer console,
otherwise you have to launch discord from commandline to check stdout
Hello, I have been working on a small thing for personal use to display an icon (specifically a silver crown but that is irrelavant for the point here) for users that have the Administrator Permission in a server. For that, I modified the forceOwnerCrown with the following patch:
patches: [
{
find: ".PREMIUM_GUILD_SUBSCRIPTION_TOOLTIP",
replacement: {
match: /,isOwner:(\i),/,
replace: ",_isOwner:$1=$self.isGuildOwner(e),"
}
}
],
so that I can sort users by permission they have and apply the owner crown to anyone I like. THIS ALREADY WORKS AND IS NOT MY ISSUE. However, I can only display the owner crown and nothing else because the function that plugin modifies (isOwner()) only returns a bool on wether or not to display the crown at all (or not). My general assumption is that there is a parent function that calls isOwner() to display all the information. Does anyone have this parent function and its dependencies for me to look at since I have no idea where to find it or how to decompile and deobfuscate the Discord Source Code
Either extract the modules and grep, or set a breakpoint
found it with console.trace(), thank you
does anyone know how I can see how many pings I have?
Check where the ping counter gets the number from
I'm new to this I don't know where to look
React devtools inspect the home button
In the corner
Then look at the code for the component
Find the component, find its render function, find what it's getting the number from
which home button lol
the one where it shows your pings?
like in this case i can say youre looking for ReadStateStore.getMentionCount()
but yeah use react devtools to see what stuff is used by a component
Not useMentionCount? Or I guess it useStateFromStores it
how do i set up react devtools?
i thought i could do it on firefox so from my very limited knowlage on this i installed the plugin and it doesnt work
also in devtools on discord it doesnt appear with the components where it should
i might be really stupid lol, im sure im doing something very wrong
That's happened to me before, I have no idea how to fix it.
try restarting your browser, then open devtools and look for a components tab (you may need to press the arrows to see it)
nope
I don't think react devtools works in firefox
extension also still shows the same thing
it does
should i install a different browser like ungoogled chromium just to test?
just seems to not work on discord for some reason
they rewrote discord just for firefox 👍
ima get ungoogled chromium and shower, with my internet it should take about the same time :p
I've never personally seen much use for react devtools, but lots of people swear by it
Native devtools have always been enough for me
Do you not use react devtools??
That's what I said yes
Horror
i watched the video in pins and from what i can tell you just search thru the parts of the button looking for the one with the on click thing so it shouldnt be that hard to do the same thing without the react devtools right? if im not completely misunderstanding this (which i probably am)
use desktop app
its harder to set up and i suck at knowing what to do for the first time
how is it harder to set up 😭
pnpm inject too stronk
ok on ungoogled chromium it works
is it possible that it uses ondragstart and ondragend or does it have to be onclick? i dont know enough web for this
because it's logical for ondraag to only happen after a bit
server
shouldnt they be like the same tho
thing is i dont think home button actually displays a ping counter
cause when DMs pop up they pop up in a seperate thing
That's true
alright i found a seperate on click
it brings me to this and now I dont know what I'm supposed to do ```js
e=>{
if (null == T)
;
else if ("string" == typeof T)
N.push(T);
else {
let {pathname: e="", state: t} = T;
N.push(e, t)
}
null != g && g(e)
}
surrounding code:
@languid field what are you trying to patch in the first place
get ping count
like total number of unread mentions?
yeah
then im thinking from there i might be able to create either a plugin or just a script i can shove into the console to connect to a waybar module so i can have my pings displayed cleanly
how can I get the user's ID in a plugin?
theres a store for it iirc
by what?
Just call the /users/@me/mentions endpoint from your statusbar
UserStore.getCurrentUser()
ty
thats recent mentions, it doesnt filter unread vs read
THATS A THING???
I think the mobile app does show number of pings, so you could maybe try to find where that gets its info from
yea, thats what i was thinking about, but for the desktop app
welp
maybe you could add a flux event for mention
because when you open discord you know how many mentions you have and then you could just keep track of the new ones
with...
i cant connect my phone to wifi if it's connected to PC
i need somebody to use HTTP toolkit for me
like with a hotspot?
the issue is im too far away
i have no wifi
my PC is connected with a 6 meter usb extension cable
discords api is documented at https://discord.sex
You’ve found the Unofficial Discord User API Documentation! These pages are dedicated to showing you all the ways that you can use Discord to make cool stuff. It is not an official source of informati...
and im still barely connected
perfect domain
hate this fucking page https://discord.com/developers/docs/topics/oauth2 so useless
Object.values(findByProps("OPENID", "IDENTIFY")); SO GOOD
HTTP Toolkit?
what is account.global_name.update 
it does use root tho so people here might not be able to help :/
i cant root waydroid
so im just screwed ig
theres a bunch of alternatives
what's the difference to devtools network tab
you can use the mobile app
just edit the underlying filesystem??????
from outside the container
yeah i tried then i failed and now i switched distros and dont have it installed so i give up on that
yeahh ones that discord wont use
apps haven't been using user certificates for a long time
unless you like modify the app yourself
which i dont know how to do
horror
i mean its safer that way ig
if somebody gets access to any of your devices they can just connect it to a mitmproxy instance with their certificate.
and you can do that on every OS except android (unless it's rooted)
tbh i would be more concerned if they had access to the device itself rather than just a certificate installed connected to mitmproxy
when you have access to a device you might only have a minute
this is just one of the easier things
a more complex one is to write malware (or skid malware from github xd)
real
im still wondering what the fuck "account.global_name.update" scope does
liar
my guess is that it's user profile related
it could also just be a dead scope with dead code left over
true
you should try using the scope directly in the client instead of from a web browser
i think #📜-js-snippets had that
honestly it looks Dead anyway
look at wreq(713938).jW
not listed there
lol nvm im blind af #🌺-regulars message
ok ive implemented #🏥-vencord-support-🏥 message (literally just copied the whitelist code and changed a bool)
I could make a toggle for whitelist/blacklist cause from what i can imagine youd never want to blacklist something but also whitelist something else
the toggle makes more sense right?
Yeah the toggle makes sense
Iirc other plugins that have a blacklist/whitelist just use a toggle
Looks good
should I hide the import customrpc if its on blacklist
at that point youd just disable customrpc right
can i even get the state of the toggle without saving & closing
also I renamed the internal setting from allowedIds to idsList which means users would lose the ids they set. Should I just leave the name as allowedIds even tho its not descriptive anymore
copy it, hide the old setting
.. what does it sound like
oh ig global name is api terminology you might not know
global name = display name

Global name is still not in the fucking user types so like 5 of my plugins error
im not (entirely) stupid
why would that be a permission that can be granted though
well
it was (?)
is there a way to create an optional plugin dependency or do you just have to tell the user "hey you can install this if you want"
no there isnt
I just had a weird idea
Like 99% of the in app assets are svgs
So theoretically you could make a plugin that changes the color to match your themes color variants
like built in themes or custom themes?
because you can change the SVGs via css
i don't think any of them use an img tag
Custom themes
I had the thought because i use the catppuccin mocha theme, and the svgs don't match the color scheme
But yeah it might also be possible with css
Just override the fill or whatever to the closest variable
that sounds like css
Probably would be hard to do optimised tho
yea, but what would it be
there are too many SVGs for it to be a bunch of patches
True actuallyt
that and you can also tint PNGs with filters
so the grayscale wumpus images and stuff too
although that'd take either a lot more math or a lot more manual work
Wouldn't overriding currentColor work in a lot of places?
Actually it might be possible to use some type of attribute selector
Since svgs probably use the same color palette for the most part
Is there a simple way to get how many messages the local user has sent in a server, and additionally change the timeframe to just the last week? I had a super horror approach going on but it didn't work at all
Your best bet is spamming the fuck out of the search endpoint
I did think about that
Cool; it's the most reliable option
Is it a bad idea? i haven't really used any endpoints before
I mean you can spam the shit out of the search in the normal client anyway
My plugin wouldn't use it more than that anyway
Cool. Do it ~50-200 times in a few seconds
YES IT WOULD
unless
do it in the background as you are going through your server prune thing
Yeah that's what i mean
I mean it seems to work fine
Is this cursed?
It's probably possible to filter the messages date to save making an extra request with for the recent messages too
this is cursed
useAwaiter exists for this BTW
i think
oh
nvm
oh maybe????
you could probably use that
That's a fucking thing??
Yop
I just moved it over let me test
trolley
ok the awaiting works
Problem is, it doesn't recall when the index changes now
Is there a similar thing so i can call it again when the index state changes?
You will set deps here?
OH WAIT
Yeah i'm stupid
It works great actually
Yeah i don't think you could filter it to just get the last week could
And sending 2 requests would probably be a problem
Hmm
doubt
just use promise.all 
I am going insane
I'm trying to make the min_id parameter for the recent request
No idea what to do
Pretty sure it's a snowflake, but sioajdiowadhwjadhaskjhdsaj how tf do i get exactly a week ago and then convert it to a snowflake
Or just get it as a snowflake in the first place
Min id is the date parameter (after _)
It's gonna make a second request to get the message count in the last week
SnowflakeUtils.fromTimestamp(Date.now() - (7 * 24 * 60 * 60 * 1000))
Something like that
is there a way to make a multi select?
or would I need to write a custom component for that setting?
Just do a dozen checkboxes, it's what everyone does
yes, i don't know because it goes away too fast and react devtools are a piece of shit that don't work while the page is paused in debugger
index.tsx: Lines 11-33
declare enum SpinnerTypes {
WANDERING_CUBES = "wanderingCubes",
CHASING_DOTS = "chasingDots",
PULSING_ELLIPSIS = "pulsingEllipsis",
SPINNING_CIRCLE = "spinningCircle",
SPINNING_CIRCLE_SIMPLE = "spinningCircleSimple",
LOW_MOTION = "lowMotion",
}
type Spinner = ComponentType<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
type?: SpinnerTypes;
animated?: boolean;
className?: string;
itemClassName?: string;
"aria-label"?: string;
}> & {
Type: typeof SpinnerTypes;
};
const { Spinner } = proxyLazy(() => Forms as any as {
Spinner: Spinner,
SpinnerTypes: typeof SpinnerTypes;
});
ty
placeholder:\i,
then replace it with whatever you want
Just make sure you have the right find
You might need to add the previous prop to the match so you don't accidentally match the parameters at the top of the function
Or find where u is defined and change that
Do you know what windows alternative to mpris would be?
Switching to linux
A few questions.
- How do I cache and use data I fetched at the plugin startup (no localStorage, it's too much data)?
- How do I disable the plugin if the data fetching failed?
- What are the dependencies?
Probably some of the functions in lazy
enjoy
const React = Vencord.Webpack.Common.React;
const ReactDOM = Vencord.Webpack.Common.ReactDOM;
const icons = Object.entries(Vencord.Webpack.findByProps("Adg"));
const tree = React.createElement(React.Fragment, {}, icons.map(([name, icon]) =>
React.createElement(icon, { key: name, size: 24 })
));
const sudo = document.createElement("div");
ReactDOM.render(tree, sudo);
Vencord.Webpack.Common.Clipboard.copy(sudo.outerHTML);
console.log("Copied");
whoops im blind you can just Vencord.Webpack.findByProps("AIcon")
pretty cool
Could someone way smarter than me take a look at this plugin and tell me if the api usage would be ok? Not sure if it's safe or a good idea
I did add a 2 second cooldown on the scroll button just to prevent rate limiting
the thumbnail image 😭
I set that ages ago and it jumpscares me every once in a while

I saw that I can use native.ts files to run code in a NodeJS environment, how do I get the result of that code in my index.ts start function?
Did you try calling the function and checking the return value
Yeah, a cors error
If it's in the normal code (index.ts)
I did not try native.ts yet, so I asked a theoretical question so I won't waste my time for something that is impossible
So you did not try calling the native function and getting its return value
Not yet, as I'm not home atm, I asked it without trying as I want to verify if it's even possible from people's experience
Let me rephrase my question.
I'm encountering a CORS error when trying to access a particular API, this is a known issue we've already surfaced to them but they aren't fixing. Will moving the method that fetches the data to native.ts and calling it from index.ts resolve this issue or will I need a proxy hosted somewhere?
Welp, after some research and digging into the built in plugins (since this is not documented). I discovered VencordNative.pluginHelpers. Would appreciate if this was documented
Is there a better way to go about applying CSS when a user's status changes? The current method I use just spam re-applies the CSS to specific elments every 1ms to keep it up to date in somewhat 'live time', but spam applying the CSS crashes Discord after a few minutes and I'm pretty sure its not the proper way to go about it. (For context, I'm making a plugin that changes status icon SVGs/masks and it works using a patch, but when a user's status changes, it seems to scrape the status element of its mask and other attributes, so to get around it, I just have a function overwrite that element's attributes)
yeah those status icons, except a patch is fine for the ones in that pop-up since their attributes never seem to change
what exactly is preventing you from just doing regular css to do..whatever it is you're trying to do?
CSS gets removed whenever a status changes since the element gets updated by Discord, which removes the custom CSS from the element
what
don't apply css to the element
don't use Dom manipulation
you can apply global css that selects the elements
which plugin does that so I can look at how its done properly?
you could just write your css in quickcss, select the element and replace it by using a pseudoelement; or if you're already making a plugin you could probably just overwrite the svg mask
just use css, without using a plugin
alright
I previously tried overwriting SVG masks, but those masks don't seem to be used once a user's status changes until the element gets reloaded/refreshed
I'll try my luck with just pure CSS
hmm yeah and a pseudoelement doesn't work on the rect but it works on the avatar, jsut need to place it manually
here's a jank example (dirty prototype css but you get the idea)
rect[mask="url(#svg-mask-status-online)"]
{ width: 0 }
.avatar_b2ca13:has(rect[mask="url(#svg-mask-status-online)"])::after
{ content: url("https://cdn.discordapp.com/emojis/1026533070955872337.webp?size=16&quality=lossless") !important;
position:relative; bottom: -20px; right: -20px;}
it will require a decent effort to make it work in other places where status indicators are and some clever length units if you want to make it work across different scaling settings etc
so maybe trying to replace them with a plugin isn't the worst idea, but it definitely can be done with just css
not super well though
replacing words with css is kinda scuffed
I'm trying to add my own Component into the TabBar on the the Homepage where you can see your Friends. I have this REGEX and I also want to match the figured it out]}), in the group. Does anyone know how I can do that?
@dull magnet can i get access to #1256395889354997771 once more for the second plugin (#1264693098873618465)
vsp @vapid oar
const dmChannel = ChannelStore.getChannel(ChannelStore.getDMFromUserId(user?.id));
const lastMessage = dmChannel ? MessageStore.getMessage(dmChannel?.id, dmChannel?.lastMessageId) : null;
This is my current code to get the last message in a dm, but it only works if you've opened the dm in the currect session. Is there a workaround/fix for this?
I should have specified how it doesn't work, lastMessageId is just null if the channel hasn't been loaded
There might be a different way to do it, channelstore maybe?
but the channel object exists?
Yeah the channel object is there
I'll leave it to someone who can help better
I don't have my computer so I can't even test things to help
Ah fair enough
is there a method to get your friends
RelationshipStore
Just ended up using restapi
Only needed it once for a script

Is it possible to do a similar thing to useStateFromStores but with datastore? from what i can tell datastore isn't a flux store, but i essentially want to re render a component every time a specific value in the datastore changes
hello can someone who is currently at their pc, and also has the epic games launcher installed with the OpenInApp Vencord plugin enabled as well as the epic games setting toggled on, click this (or actual url: https://store.epicgames.com/en-US/u/5cc7090ccc3644f19ec7b81a740aec26) and send me a screenshot of ur epic games launch when it pops up?
what's gonna happen
idk if it will like open up a profile or if it will do something else.
how do I access erlpack on Vesktop?
Web doesn't use erlpack
Thanks!
i can't figure out how to decode it even on canary
turns out that specific OP code is only processsed by mobile isn't actually sent to FluxDispatcher on PC
ok wait maybe im just crazy cuz the event doesn't even get sent to the websocket anymore
i think i mistook it for a ping message
yeah the event just doesn't exist oopsie!!
howdy 🫡 if i'm implementing an optional feature into a plugin that requires a native script, does the entire plugin become incompatible with the web version, or can platform checks be implemented that prevent incompatible platforms from using said feature?
you can simply use IS_WEB / IS_DESKTOP
can i make a setting selection not selectable if IS_WEB or do i need to implement the check within the logic
nevermind, seems like just adding disabled: IS_WEB works
the compiler will automatically strip unreachable code
so you can just use if statements / ternaries with the definitions
so i should probably both remove the settings options on web and add the if statements into the logic
thanks
so, i added DeepL support to the translate plugin. since this violates the plugin rules and i can't create a PR, can i still post it in #1256395889354997771, or is it totally not allowed to be shared?
Is it possible to embed an iframe into a popup from a plugin?
I was actually reverse engineering the deepl api a while ago and managed to translate without api key, but the rate limits were too strict
i actually wanted to use my pro API key anyways, so i more made this for me
but i noticed there were over 20 👍 reactions on the feature request
so i figured i would just make it happen since it seemed simple enough. but yeah, i did notice it violates the plugin rules
so at the very least, i wanted to share it in the feature request issue
assuming it's okay to share it
I think it's fine, since the plugin still works without deepl
it's just an option for people who have it
that rule is mainly about avoiding plugins that most users won't be able to use
so you're saying it's fine to commit, too?
like if you made a deepl only plugin, it wouldn't be allowed
but since the translate plugin still works even without, it's fine to have
yeah, i have it default to google translate still
also most people don't realise that you can use a lot of services without an api key
like google translate (technically you need a key for it too), virustotal, etc
yeah, that's fair. you do really need an API key for deepl though haha
well technically not xD
but the rate limit is too strict..
it might be worth a shot to reverse engineer their android app and yoink its key / headers

so... wait on the pr? 
you can pr it for now
okay. and while i have you, is something like this worth adding an author for the plugin? i don't really know what level/amount of contribution is worth slapping a name on it or not

i may have done that in the past
i dont have them now though
is there a way to package a node.js module into a plugin properly with webpack or smth? i'm trying to write a websocket server inside a plugin to connect with a browser extension but i can assume installing an extra dependency is a big no-no
i got like halfway through writing the server before i realised it was pulling the dependency from my global dependencies 😭
httptoolkit and an emulator 
or your phone if you're rooted
it should be packaged in automatically by esbuild afaik
also no, we dont use webpack to bundle vencord. we modify discord's own webpack
we use esbuild to bundle it all into two or 3 files
node, renderer, preload
https://github.com/nyakowint/vc-premid ive done this already and got reprimanded at least a couple times lol
PreMiD desktop app alternative. Contribute to nyakowint/vc-premid development by creating an account on GitHub.
don't do this if you're PRing a plugin though
no fun allowed, smh
Anyone know if its possible with SettingsSliderComponent to change the text it says when the slider is at max? Say the slider is from 1 to 10, if it was on 10 it would say "Infinite". Maybe there is a better way of doing what im thinking
installing an extra dependency is a big no-no
generally big bloated packages or things you can do with a couple lines of code or fetch() is a no
but ask v its ultimately their decision
what plugin are you making
basically spotify integrations but YouTube Music
lastfm rich presence + a ytm scrobbler
yes but also listening a long in the future
not possible
that will take 10 morbillion years to get right though and i start school soon
i have methods 😈
already wrote an entire extension to scrobble ytm efficiently
how should i?
OLD:
/(?<=(?:},{|\[{)type:\i\.ABu\..*?,name:")(.*?)"(.*?icon:{.*?},.*?enabled:)(?:!(\d))(?=,?)/g```
NEW:
```js
/(?<=(?:},{|\[{)type:\i\.\w{0,8}?\..{0,20},name:")(.{0,20})"(.{0,40}?icon:\{.{0,225}?\},.{0,150}?enabled:)(?:!(\d))(?=,?)/g```
Is the new match by far better?
no
what should i change?
rewrite the whole thing
HORROR
what are you trying to patch
it's supposed to do it globally and it adds stuffto the string so it can replace it
and it's based on if enabled is !0 or !1
Why the replace dance when you can just call $self.whatever()
yep! it took me like an hour to finish that regex lol
i mean adhd doesn't help that either
God is sending another flood
my brain has a very big feature of not working correctly!
you're heavily overcomplicating it
keep it simple
why are you matching soooo much
match as little as possible
don't be overly precise
i was trying to get to the enabled spot without it going over, and that was so i could collect that and use it for the replace thingy
but i will try once more!
you can just match for enabled:!1 instead of both !0 and !1
wtf how is my brain that stupid to not think of that.... wut.
how would i go about patching the same thing that another plugin patches, without conflicting with the original plugin
predicate with Vencord.plugins.isPluginEnabled(name), if the predicate is false patch normally, if its true work the patch around the other plugin's
remember to see which plugin's patch applies first, u might have to modify the other one
or just make an api
is there a way to know what order they will be applied in?
what do u want to patch
(i have a plugin that runs into the same issue)
Or write the patch in a different way, often you can put it a few statements away and it'll still work fine
the username rendering function, but showmeyourname already patches it.
and i cant exactly edit smyn, because its for an #1256395889354997771
iirc theres a way to define incompatable plugins? lemme check
i'd rather not though
then youre out of luck
idk what else to tell you
just work the patch around the code
I had a conflict with smyn too, which I fixed by applying the custom rendering in a separate statement https://github.com/Kyuuhachi/VencordPlugins/commit/d1acb8804
vee said this, not entirely sure what they were suggesting though.
write a patch that doesn't break when the code includes the other plugin patch or write an API
they are pretty clear
first option is better since an api would likely be overkill
yea but im shit with patches & regex
Git gud then
would an API even be feasible, given the fact its a userplugin?
nop
me and FriendsSince
I think i have dementia i dont remember sending this gif
@balmy sky someone wanted this plugin and I fixed it but wha-
You didn't you regex for the r.default.STICKER_MESSAGE either 😭
I was like did bro just start making stuff in February or
Tbf you couldn't back then but I'm sure you could've fixed it! (That's the find)
What even is that plugin
Sticker Blocker
Someone brought it to me because they couldn't find it
And they wanted it so I fixed it
And they are happy ig idrk
I see no point in it really
Just deal with it
Fair
TBH I just robbed clone emoji for the context menus
It's almost 3am and I didn't want to fix it if it was actually broken
Not the best find but it will do
A month or 2 ago
This might be in a diff branch I don't even remember merging the branch tho
Nvm
v1.8.5
wait why use regex in the find when a string works fine?
There are 2 .STICKER_MESSAGE and I didn't have my discord open to look I just did that and knew it would work
If you look into that module There are plenty of other strings that you can find.
I use regex in finds when I don't want to do a proper find because it's late at night and I'm tired 👍
That's basically the same find as sams
That was the point
I didn't have discord open either way
Normally for that I will just copy a random string from the plugin, minified variables and all
My discord was stuck loading because I had bytes
I had bps
1 bps *
I could easily make that find to a string since r.STICKER_MESSAGE uses a : and I believe l.Z.STICKERMESSAGE doesn't
I apparently have 2 regex finds this one I'm replying to and find: /\i\.\i\.APP_ICON_UPSELL/
I forgot why app icon is like that but I believe it.was because I would've had to do a really long find at the time
How does the extension patches discord? (I have yet to see the source code). I'm trying to make a small patch in a website's js code and can't seem to figure out how to patch the webrequest response
just use userscript it's easiest
I tried that too. Should I intercept the web request or like find and change the variable I'm trying to change?
- not plugin development. use #🪅-progaming
- stop with https://xyproblem.info. state your actual issue and goal
is there a way to get a channel object with the channel id and guild id
hello yes I would like to buy some channels
You can literally buy discord channels
is there a way to use Parser.parse(), but in what i could call a "guild context"? eg. this would show roles, mentions would have nicknames, channels wouldn't be prefixed by guild name
or another method that exists to do so
global (what i don't want)
guild (what i want)
ty
where was this information when I needed it the most
is is possible to see everything subscribed to a flux
search for the event name?
FluxDispatcher._subscriptions might be your friend
ty
native script
cant you edit headers from native
yes
(i think so)
(decompiled source)
this shouldnt actually matter
1s

the only commands "limited" clients can do are SendNotification and Requestinfo or whatever we're safe
lmao
probably so random website cant mess w your overlay i guess
not that any would
Where can i find a function to send a message in the current channel? i found sendMessage in the discord utils but it doesn't reply to whatever you have selected as a reply
look at VoiceMessage plugin
Alright, I give up trying to fix this myself. Why is my Native undefined when printed out and why is my native.ts not working correctly? I've checked various other plugins that do this and it all seems to be correct. I do fully restart my Discord as well.
const Native = VencordNative.pluginHelpers.PersonalBadges as PluginNative<typeof import("./native")>;
And I think due to this, I get this error whenever I try to use something from there:
TypeError: Cannot read properties of undefined
I could do it again but I always quit from the tray and reopen
Yep
Sorry but what exactly do you mean? This is kind of my first time trying to do this stuff
go into to devtools and type VencordNative.pluginHelpers
Ah I get it now, thanks
Alright fixed my issue! I guess I couldn't have any spaces within the name of my plugin and when I saw it in the pluginHelpers it looked out of place with the others. I didn't see anywhere that you couldn't though but probably should've saw and followed how the other plugins were anyways. I guess something I'll keep that in mind for the future then.
All that time just for that-
Thanks though
was your plugin name Personal Badges?
Pretty much
you prob just had to do VencordNative.pluginHelpers["Personal Badges"] then
Ah
It's fine though, I was probably gonna change it not to have a space soon anyways but thanks, guess I could also do that if I ever wanted to then
yep yep
Discord doesn't load 100% of it's styles through webpack
the concept of relying entirely on wreq.f.css instead of mutationObserver isn't possible then
it is for all the others beside the initial one
which is no big deal but we already decided to use mutation observer anyway
what would be the most sane way to get the URL for that link from a plugin that starts at StartAt.Init
before setting up the mutation observer query the existing css
after that it should all be catch in the mutation observer
I'm not using mutation observer at this point ngl
(even the initial if it wasn't loaded yet)
huh?
you are gonna query once only
for the already existing ones before you start the observer
there are no issues with that
I feel like what I am getting with wreq.f.css is going to be cleaner than a mutationobserver
how
Api.Styles.styleListeners - new Set<(styles: string) => void>();
plugins\_api\styleListener.ts
// ... cleaned version of your wreq listener
for (const listener of Api.Styles.styleListeners)
listener(styles);
// ...
basically all my plugin ideas require this api
I don't know how to make an API require restart if it has no patches, because techincally this one does
start of StyleListenerAPI
const wreq = await new Promise<WebpackInstance>(r => beforeInitListeners.add(r));
const chunksLoading = new Set<string>();
const handleChunkCss = wreq.f.css;
wreq.f.css = function (this: unknown) {
const result = Reflect.apply(handleChunkCss, this, arguments);
if (chunksLoading.has(arguments[0]))
return result;
chunksLoading.add(arguments[0]);
if (!(Array.isArray(arguments[1]) && arguments[1].length > 0))
return result;
Promise.all(arguments[1]).then(async () => {
await Promise.all(arguments[1]);
chunksLoading.delete(arguments[0]);
const cssFilepath = wreq.p + wreq.k(arguments[0]);
const styles = await fetch(cssFilepath)
.then(res => res.text()).catch(() => { });
if (!styles) return;
for (const listener of Styles.styleListeners)
listener(styles);
});
return result;
};
I'll make the proper api and include in my webpack changes pr
I wanna try to get it merged soon
but if that doesn't happen I'll port to current vencord
okay
what is the most sane way to handle the initial style in this?
StartAt.Init so document.head is still null
requestAnimationFrame(() => document.querySelector
is cleanest solution I have thought of
can we mutation observer already there
if we are gonna use a mutation observer already there it's better to only use it
and avoid webpack patch
mutation observer can only be placed on document, so you still need a second observer
also somehow using a mutation observer is slower than window.requestAnimationFrame(()=>{...})
how are you benchmarking that?
2 plugins, one logs one the first observed mutation, the other logs on requestAnimationFrame, requestAnimationFrame always is first
are you requesting frames recursively?
no
or the first frame generated already contains head
first generated frame contains head
is there a way to modify/intercept requests/responses, specifically for message loading
That's almost certainly the wrong layer to modify
ok i tried modifying fetchMessages, but that just returns true, so i used the function it calls with my own message objects but the client doesnt seem to care and still fetches the messages in the channel from the api, any ideas?
and you are trying to do what?
How would I add another sound to this? I tried installing react dev tools to opera and doing it but I have no idea what to do with what I find.
Are there any documentations other than just looking at plugins and the starting plugin documentation?
I'm not using vencord on it.
Is there an easy way to add more settings sections?
I'll add it on chrome, but what would I do with what I find it react devtools?
Go to components and then use the picker to click on what you want to inspect.
actually prob not to encourage just using standard plugin settings whoops time to find some stupid ass way to do that anyway :3
Yeah, I got that far, but what do you do with this?
you can use a custom component for a setting
i know, also i found the stupid way to do it already :3 its less so configuring the plugin and more so a utility that id place into the discord settings + i need space which a modal cant provide
you are gonna have to reverse engineer how discord obtains the list of sound packs, find a way to add your own and also have to deal with settings sync not overriding your custom pack
which means if you have no experience that's gonna be complicated
I'm willing to help you in making this plugin, but I have to do it later. I'm busy right now.
ping me in an hour or two
for future reference (i guess i should add that you shouldnt use this for normal plugin settings ofc)
import { SettingsTab, wrapTab } from "@components/VencordSettings/shared";
import definePlugin, { StartAt } from "@utils/types";
import SettingsPlugin from "plugins/_core/settings";
import { Card, Forms, TabBar, TextInput } from "@webpack/common";
function CustomSettingsSection() {
return (
<SettingsTab title=":3">
<TextInput type="text" placeholder="meow" />
</SettingsTab>
);
}
export default definePlugin({
name: ">:3",
description: "asdf",
authors: [],
startAt: StartAt.Init,
start() {
SettingsPlugin.customSections.push(() => {
section: "mreow",
label: "cool section",
element: wrapTab(CustomSettingsSection, "mreow"),
classname: ""
});
}
});
well the settings plugin deliberately lets you add your own sections for exactly such purposes
that's why customSections exists
so it's completely fine to use as long as there's a good reason to
it's already used by vesktop (that's the main reason it was added, but plugins can make use of it too)
index.ts: Lines 40-49
const customSettingsSections = (
Vencord.Plugins.plugins.Settings as any as { customSections: ((ID: Record<string, unknown>) => any)[] }
).customSections;
customSettingsSections.push(() => ({
section: "Vesktop",
label: "Vesktop Settings",
element: SettingsUi,
className: "vc-vesktop-settings"
}));
lmao alright but thats kinda what i thought, added because it was needed for something else and not for plugins
thats also why i thought it was discouraged
how would i get the className of the Mutual Servers element
you want #🎨-theme-development
nah im trying to add another entry there for group dms
look at it's component code and you will find where it adds the classes
or even easier actually
look in the html and find the class name with the hash
search for it in devtools and you are gonna find the module that exports them
then just write a filter to find that module
uhh how do I have the vendor developer mode on
ctrl+shift+i
and set it to dock in a seperate window
but it doesnt seem to have a class name to differentiate it from mutual friends
why isnt this the default
idk
but i prefer dock right usually
Ah yes I'd like my viewport to be made significantly smaller AND have a devtools panel that is unusably small
for css stuff, it's usually fine
honestly I just toggled it
it isnt that bad
but for searching through Discord code
absolutely No
if you use the console in any other way we cant be friends
most of the time for css, using it like tha tis fine
and docking as a seperate window is kinda weird in discord because pressing ctrl+shift+i when main discord is focused and devtools is already open closes devtools instead of focusing it (like it does in google chrome)
but also dungeons cringe, so i don't want to be friends with you (although f6 is best dungeon)
skill issue
cata 39 on both accs before wipe 
ew
I only do when I’m lacking screen space from having an entire monitor reserved for the 8 hour long video about yellow killing show
(average dungeons player btw)
yea
anyone know how discord fetches the list of favorite gifs? i tried monitoring network activity but it only fetches images and does not perform any other api request
it is part of the client settings
there is no specific api route for gifs only
it's stored inside the settings protobuf data
Vencord.Webpack.Common.UserSettingsActionCreators.FrecencyUserSettingsActionCreators.getCurrentValue().favoriteGifs.gifs
which is fetched via /users/@me/settings-proto/*
and returns protobuf bytes as base64
Thanks for the support 🙏
Vencord vim keybinds plugin when 😨
When someone makes one
Working on that one
Maybe within the next month
how do i get localStorage inside a plugin? I want to save a value
DataStore
ah, thanks!
why is this not working? (it's not even appearing in the plugin list)
nvm none of my userplugins are working and I am officially an idiot
why are you installing plugins with nix
Presumably they use nix and want to use vencord with user plugins
thats why god made vesktop
Vee is god confirmed?
nop
yes
is there a docs for this 🤔
The closest you might get is https://discord.sex
You’ve found the Unofficial Discord User API Documentation! These pages are dedicated to showing you all the ways that you can use Discord to make cool stuff. It is not an official source of informati...
no
it's proprietary discord code why would there be docs
you need to reverse engineer things
I wanna star this
i have no idea what you are talking about
Is there a starboard?
I deleted it cause it's funnier without the context
(also unnecessary nix yapping noone gives a shit)
oh 😭
i was gonna say "thats a pretty bad look you made for yourself"
The fact that the other messages were deleted is fucking hilarious
what
why
it was in reply to someone asking why I use nix for plugins
the answer is because I use nix for vencord, and I was explaining that my user plugins option only allows putting files in (not strings)
the message was deleted :(
Why? :(
you had to be ther
wait starboard is gone‽‽
Yes, it was murdered
what happened
murdered
why
idk, probably too much shitposting on it
or, it got retired because huskboard might be coming back
Probably the first one though
😭 i loved starboard
just to verify, api key's are fine, as long as they're not required?
iirc yea
how do i get the mesages from before? i'm trying to get all the messages, in a DM
i understand this but it only returns a certain amount of messages i wanna get the ones before the last one.
MessageStore.getMessages
do you mean load more messages for a channel
yes
By fetching them but that's api abuse if you fetch the entire history
figure it out yourself
oh, i didnt see the all the messages part, oops
oh ok

@hushed loomi need the function!!!
me when im stupid
I see some people noted looking to intercept events,
according to the dispatcher flow, events are divided into 3 parts.
- Intercept (return
truehere means events scraped) - ActionDispatchers (list of events to process given event object)
- Subscribers (list of events to post-process given event object)
In order to modify an event, a callback need to be placed somewhere on Intercept or ActionDispatcher stage. I wouldn't recommend to do the latter. However making a wrapper for "Intercepting Event" and "No Intercept Event" would be good to make a hassle free incoming event filter.
I think an extension of FluxDispatcher type definition regarding interception and how it works can be handled somewhere on utilities or similar like that? Well, thats my 2-cents regarding how it works.
can someone suggest a name for a plugin that replaces the tooltip of the mute/deafen buttons with a volume slider?
similar to the video player
Yay okay so
I want to make a dialog but only know the Alerts function is there a way to display HTML/React code
Alerts.show({
title: "Need html",
body: `How do I put html in a dialog like this`,
});
Use JSX
I know but how to display it using Alerts or do I need another function
You can use Alerts.show for that
oh I tried but it didnt work
Alerts.show({
title: "Get ricked lmao",
body: `<iframe width="560" height="315" src="https://www.youtube.com/embed/X-cfWM0BC_4?si=Vfcp5PWnCHpKOxH_" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>`,
});


