soggy plugin (#256)
Some checks are pending
Test / Test (push) Waiting to run

* Update constants.ts

* Update index.tsx

* Update README.md

* soggy plugin

* Edits

---------

Co-authored-by: thororen <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
sliwka 2025-05-09 17:04:13 +00:00 committed by GitHub
parent bb0b4897b4
commit c7298da33b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 156 additions and 1 deletions

View file

@ -11,7 +11,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
### Extra included plugins
<details>
<summary>171 additional plugins</summary>
<summary>172 additional plugins</summary>
### All Platforms
@ -143,6 +143,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
- SidebarChat by Joona
- Signature by Ven, Rini, ImBanana, KrystalSkull
- Slap by Korbo
- Soggy by sliwka
- SoundBoardLogger by Moxxie, fres, echo, maintained by thororen
- SplitLargeMessages by Reycko
- SpotifyActivityToggle by thororen

View file

@ -0,0 +1,150 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { EquicordDevs } from "@utils/constants";
import { ModalProps, ModalRoot, openModal } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
import { React } from "@webpack/common";
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '.iconBadge,"top"');
function SoggyModal(props: ModalProps) {
if (settings.store.enableSong) {
React.useEffect(() => {
const song = document.createElement("audio");
song.src = settings.store.songLink;
song.play();
return () => {
song.pause();
song.remove();
};
}, []);
}
const boop = (e: React.MouseEvent<HTMLImageElement>) => {
const img = e.currentTarget;
const { offsetX, offsetY } = e.nativeEvent;
const region = { x: 155, y: 220, width: 70, height: 70 };
if (
settings.store.enableBoop &&
offsetX >= region.x &&
offsetX <= region.x + region.width &&
offsetY >= region.y &&
offsetY <= region.y + region.height
) {
const boopSound = new Audio(settings.store.boopLink);
boopSound.play();
}
};
return (
<ModalRoot {...props}>
<img
src={settings.store.imageLink}
onClick={boop}
style={{ display: "block" }}
/>
</ModalRoot >
);
}
function buildSoggyModal(): any {
openModal(props => <SoggyModal {...props} />);
}
function SoggyButton() {
return (
<HeaderBarIcon
className="soggy-button"
tooltip={settings.store.tooltipText}
icon={() => (
<img
alt=""
src={settings.store.imageLink}
width={24}
height={24}
draggable={false}
style={{ pointerEvents: "none" }}
/>
)}
onClick={() => buildSoggyModal()}
selected={false}
/>
);
}
const settings = definePluginSettings({
enableSong: {
description: "Enable the song that plays after clicking the button",
type: OptionType.BOOLEAN,
default: true,
},
enableBoop: {
description: "Let's you boop soggy's nose",
type: OptionType.BOOLEAN,
default: true,
},
tooltipText: {
description: "The text shown when hovering over the button",
type: OptionType.STRING,
default: "the soggy",
},
imageLink: {
description: "URL for the image (button and modal)",
type: OptionType.STRING,
default: "https://soggy.cat/img/soggycat.webp",
},
songLink: {
description: "URL for the song to play",
type: OptionType.STRING,
default: "https://incompetech.com/music/royalty-free/mp3-royaltyfree/Sneaky%20Snitch.mp3",
},
boopLink: {
description: "URL for the boop sound",
type: OptionType.STRING,
default: "https://github.com/Capeling/soggy-mod/raw/refs/heads/main/resources/honk.wav",
}
});
export default definePlugin({
name: "Soggy",
description: "Adds a soggy button to the toolbox",
authors: [EquicordDevs.sliwka],
settings,
patches: [
{
find: "toolbar:function",
replacement: {
match: /(function \i\(\i\){)(.{1,200}toolbar.{1,450}mobileToolbar)/,
replace: "$1$self.addIconToToolBar(arguments[0]);$2"
}
}
],
// taken from message logger lol
addIconToToolBar(e: { toolbar: React.ReactNode[] | React.ReactNode; }) {
if (Array.isArray(e.toolbar))
return e.toolbar.push(
<ErrorBoundary noop={true}>
<SoggyButton />
</ErrorBoundary>
);
e.toolbar = [
<ErrorBoundary noop={true} key={"MessageLoggerEnhanced"} >
<SoggyButton />
</ErrorBoundary>,
e.toolbar,
];
},
});

View file

@ -1070,6 +1070,10 @@ export const EquicordDevs = Object.freeze({
name: "Cootshk",
id: 921605971577548820n,
},
sliwka: {
name: "sliwka",
id: 1165286199628419129n,
},
} satisfies Record<string, Dev>);
// iife so #__PURE__ works correctly