mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-23 13:27:03 -04:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
e5a1161327
22 changed files with 281 additions and 203 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "equicord",
|
"name": "equicord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.9.5",
|
"version": "1.9.6",
|
||||||
"description": "The other cutest Discord client mod",
|
"description": "The other cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Equicord/Equicord#readme",
|
"homepage": "https://github.com/Equicord/Equicord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -67,7 +67,7 @@ export const _handleCommand = function (cmd: Command, args: Argument[], ctx: Com
|
||||||
sendBotMessage(ctx.channel.id, {
|
sendBotMessage(ctx.channel.id, {
|
||||||
content: `${msg}:\n${makeCodeblock(reason)}`,
|
content: `${msg}:\n${makeCodeblock(reason)}`,
|
||||||
author: {
|
author: {
|
||||||
username: "Vencord"
|
username: "Equicord"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a Discord client mod
|
|
||||||
* Copyright (c) 2024 Vendicated and contributors
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { localStorage } from "@utils/localStorage";
|
|
||||||
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize } from "@utils/modal";
|
|
||||||
import { findByProps } from "@webpack";
|
|
||||||
import { Button, FluxDispatcher, Forms, React, showToast, Text, TextInput, Toasts, useState } from "@webpack/common";
|
|
||||||
|
|
||||||
|
|
||||||
interface AppIcon {
|
|
||||||
id: string,
|
|
||||||
iconSource: string,
|
|
||||||
name: string,
|
|
||||||
isPremium: boolean;
|
|
||||||
}
|
|
||||||
function AppIconModal(props: ModalProps) {
|
|
||||||
const [name, setName] = useState("");
|
|
||||||
const [imageUrl, setimageUrl] = useState("");
|
|
||||||
|
|
||||||
function addAppIcon(name, url) {
|
|
||||||
const appIcons = JSON.parse(localStorage.getItem("vc_app_icons") ?? "[]");
|
|
||||||
const id = `${name.replaceAll(" ", "")}_${Date.now()}`; // avoid crashing if repeated name
|
|
||||||
const icon = {
|
|
||||||
"id": id,
|
|
||||||
"iconSource": url,
|
|
||||||
"isPremium": false,
|
|
||||||
"name": name
|
|
||||||
} as AppIcon;
|
|
||||||
|
|
||||||
|
|
||||||
appIcons.push(icon);
|
|
||||||
findByProps("M9", "UZ", "QA").UZ.push(icon);
|
|
||||||
findByProps("M9", "UZ", "QA").QA[icon.id] = icon;
|
|
||||||
showToast("Added custom app icon!", Toasts.Type.SUCCESS);
|
|
||||||
props.onClose();
|
|
||||||
const oldIcon = findByProps("getCurrentDesktopIcon").getCurrentDesktopIcon();
|
|
||||||
|
|
||||||
let random_icon = Object.keys(findByProps("UZ")).filter(icon => icon !== oldIcon) as [];
|
|
||||||
random_icon = random_icon[Math.floor(Math.random() * random_icon.length)];
|
|
||||||
|
|
||||||
FluxDispatcher.dispatch({
|
|
||||||
type: "APP_ICON_UPDATED",
|
|
||||||
id: random_icon
|
|
||||||
});
|
|
||||||
FluxDispatcher.dispatch({
|
|
||||||
type: "APP_ICON_UPDATED",
|
|
||||||
id: oldIcon
|
|
||||||
});
|
|
||||||
localStorage.setItem("vc_app_icons", JSON.stringify(appIcons));
|
|
||||||
}
|
|
||||||
|
|
||||||
return <ModalRoot {...props} size={ModalSize.MEDIUM}>
|
|
||||||
<ModalHeader>
|
|
||||||
<Text color="header-primary" variant="heading-lg/semibold" tag="h1" style={{ flexGrow: 1 }}>Add a custom app icon:</Text>
|
|
||||||
<ModalCloseButton onClick={props.onClose}></ModalCloseButton>
|
|
||||||
</ModalHeader>
|
|
||||||
<ModalContent>
|
|
||||||
<br />
|
|
||||||
<Forms.FormSection title="Name">
|
|
||||||
<Forms.FormText type="description">
|
|
||||||
This name will be shown in the App Icons list.
|
|
||||||
</Forms.FormText>
|
|
||||||
<TextInput
|
|
||||||
placeholder="My awesome Custom App Icon!"
|
|
||||||
value={name}
|
|
||||||
onChange={setName}
|
|
||||||
/>
|
|
||||||
</Forms.FormSection>
|
|
||||||
<br />
|
|
||||||
<Forms.FormSection title="Image URL">
|
|
||||||
<Forms.FormText type="description">
|
|
||||||
Paste here your image URL to upload your icon (.webp, .jpg, .jpeg, .png, .gif, .ico and Discord Icons, Emojis, PFPs, etc.).
|
|
||||||
</Forms.FormText>
|
|
||||||
<TextInput
|
|
||||||
placeholder="https://cdn.discordapp.com/emojis/1098881040900173895.gif"
|
|
||||||
value={imageUrl}
|
|
||||||
onChange={setimageUrl}
|
|
||||||
/>
|
|
||||||
</Forms.FormSection>
|
|
||||||
</ModalContent>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
addAppIcon(name, imageUrl);
|
|
||||||
}}
|
|
||||||
disabled={!name || !imageUrl && imageUrl.match(/(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?\/[a-zA-Z0-9]{2,}|((https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z]{2,}(\.[a-zA-Z]{2,})(\.[a-zA-Z]{2,})?)|(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}\.[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})?/) !== undefined}
|
|
||||||
>
|
|
||||||
Add Icon
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={props.onClose}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
look={Button.Looks.LINK}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalRoot>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AppIconModal;
|
|
|
@ -4,95 +4,88 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Link } from "@components/Link";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { CodeBlock } from "@components/CodeBlock";
|
||||||
import { Devs, EquicordDevs } from "@utils/constants";
|
import { Devs, EquicordDevs } from "@utils/constants";
|
||||||
import { localStorage } from "@utils/localStorage";
|
import definePlugin, { OptionType, PluginSettingComponentDef } from "@utils/types";
|
||||||
import { closeAllModals, openModal } from "@utils/modal";
|
import { Forms, React, TextArea } from "@webpack/common";
|
||||||
import definePlugin from "@utils/types";
|
|
||||||
import { findByProps } from "@webpack";
|
|
||||||
import { Button, FluxDispatcher, Forms, React, showToast, Toasts } from "@webpack/common";
|
|
||||||
|
|
||||||
import AppIconModal from "./AppIconModal";
|
type Icon = {
|
||||||
|
id: string,
|
||||||
|
iconSource: string,
|
||||||
|
isPremium: boolean,
|
||||||
|
name: string,
|
||||||
|
};
|
||||||
|
|
||||||
function removeAppIcon() {
|
const settings = definePluginSettings({
|
||||||
const current_icon = findByProps("getCurrentDesktopIcon").getCurrentDesktopIcon();
|
icons: {
|
||||||
let icons = JSON.parse(localStorage.getItem("vc_app_icons") || "[]");
|
description: "Icons to add",
|
||||||
const index = icons.findIndex(icon => current_icon === icon.id);
|
type: OptionType.COMPONENT,
|
||||||
if (index !== -1) {
|
restartNeeded: true,
|
||||||
icons = icons.filter(e => e.id !== current_icon);
|
component: iconSettingsComponent
|
||||||
delete findByProps("M9", "UZ", "QA").QA[current_icon];
|
}
|
||||||
delete findByProps("M9", "UZ", "QA").UZ[findByProps("M9", "UZ", "QA").UZ.findIndex((icon => current_icon === icon?.id))];
|
|
||||||
localStorage.setItem("vc_app_icons", JSON.stringify(icons));
|
|
||||||
showToast("Icon successfully deleted!", Toasts.Type.SUCCESS);
|
|
||||||
FluxDispatcher.dispatch({
|
|
||||||
type: "APP_ICON_UPDATED",
|
|
||||||
id: "AppIcon"
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
showToast("Cannot delete native App Icons!", Toasts.Type.FAILURE);
|
function iconSettingsComponent(props: Parameters<PluginSettingComponentDef["component"]>[0]) {
|
||||||
return;
|
const [state, setState] = React.useState(settings.store.icons ?? "");
|
||||||
|
|
||||||
|
function handleChange(newValue: string) {
|
||||||
|
setState(newValue);
|
||||||
|
props.setValue(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return <Forms.FormSection>
|
||||||
|
<Forms.FormTitle>Icons</Forms.FormTitle>
|
||||||
|
<Forms.FormText>The icons you want to add.</Forms.FormText>
|
||||||
|
<CodeBlock lang="yaml" content={"# Config Format - New Lines are separators\nName: Url"} />
|
||||||
|
<TextArea type="text" value={state} onChange={handleChange} />
|
||||||
|
</Forms.FormSection>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCustomIcons(_match: string, original: string) {
|
||||||
|
var icons: Icon[] = [];
|
||||||
|
const settingsIcons = settings.store.icons?.split("\n") as string[];
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
for (const icon of settingsIcons) {
|
||||||
|
const matched = /([^:]+):\s*(.+)/.exec(icon);
|
||||||
|
if (!matched || matched.length < 3) continue;
|
||||||
|
|
||||||
|
const name = matched[1].trim(),
|
||||||
|
iconSource = matched[2].trim();
|
||||||
|
|
||||||
|
const idName = name
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\s/g, "_")
|
||||||
|
.replace(/\W/g, "#");
|
||||||
|
|
||||||
|
icons.push({
|
||||||
|
id: `CustomAppIcon-${index}:${idName}`,
|
||||||
|
iconSource,
|
||||||
|
isPremium: false,
|
||||||
|
name
|
||||||
|
});
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const outIcons = icons.map(i => JSON.stringify(i)).join(",");
|
||||||
|
|
||||||
|
return `[${original}${icons.length > 0 ? "," : ""}${outIcons}]`;
|
||||||
|
}
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "CustomAppIcons",
|
name: "CustomAppIcons",
|
||||||
description: "Add/upload custom (In-)App Icons.",
|
description: "Allows you to add your own app icons to the list.",
|
||||||
authors: [Devs.HappyEnderman, EquicordDevs.SerStars],
|
authors: [Devs.nakoyasha, EquicordDevs.SimplyData],
|
||||||
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: /\i\.\i\.APP_ICON_UPSELL/,
|
find: "APP_ICON_HOLO_WAVES}",
|
||||||
replacement: [
|
replacement: {
|
||||||
{
|
match: /\[({[^]*?})\]/,
|
||||||
match: /\w+\.jsx\)\(\w+,{markAsDismissed:\w+,isCoachmark:\w+}\)/,
|
replace: getCustomIcons,
|
||||||
replace(str) {
|
|
||||||
return str + ",$self.addButtons()";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
start() {
|
|
||||||
const appIcons = JSON.parse(localStorage.getItem("vc_app_icons") ?? "[]");
|
|
||||||
for (const icon of appIcons) {
|
|
||||||
findByProps("M9", "UZ", "QA").UZ.push(icon);
|
|
||||||
findByProps("M9", "UZ", "QA").QA[icon.id] = icon;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stop() {
|
|
||||||
|
|
||||||
},
|
|
||||||
addButtons() {
|
|
||||||
|
|
||||||
const { editorFooter } = findByProps("editorFooter");
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button color={Button.Colors.BRAND_NEW} size={Button.Sizes.MEDIUM} className={editorFooter} onClick={() => {
|
|
||||||
openModal(props => <AppIconModal {...props} />);
|
|
||||||
}}>
|
|
||||||
Add Custom App Icon
|
|
||||||
</Button>
|
|
||||||
<Button color={Button.Colors.RED} size={Button.Sizes.MEDIUM} className={editorFooter} onClick={removeAppIcon}>
|
|
||||||
Remove Custom selected App Icon
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
settingsAboutComponent: () => {
|
|
||||||
return (
|
|
||||||
<><Forms.FormTitle>
|
|
||||||
<Forms.FormTitle>How to use?</Forms.FormTitle>
|
|
||||||
</Forms.FormTitle>
|
|
||||||
<Forms.FormText>
|
|
||||||
<Forms.FormText>Go to <Link href="/settings/appearance" onClick={e => { e.preventDefault(); closeAllModals(); FluxDispatcher.dispatch({ type: "USER_SETTINGS_MODAL_SET_SECTION", section: "Appearance" }); }}>Appearance Settings</Link> tab.</Forms.FormText>
|
|
||||||
<Forms.FormText>Scroll down to "In-app Icons" and click on "Preview App Icon".</Forms.FormText>
|
|
||||||
<Forms.FormText>And upload your own custom icon!</Forms.FormText>
|
|
||||||
<Forms.FormText>You can only use links when you are uploading your Custom Icon.</Forms.FormText>
|
|
||||||
</Forms.FormText></>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
|
||||||
|
import { migratePluginSettings } from "@api/Settings";
|
||||||
import { Devs, EquicordDevs } from "@utils/constants";
|
import { Devs, EquicordDevs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { Menu } from "@webpack/common";
|
import { Menu } from "@webpack/common";
|
||||||
|
@ -22,8 +23,9 @@ const Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
migratePluginSettings("EmojiDumper", "emojiDumper");
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "emojiDumper",
|
name: "EmojiDumper",
|
||||||
description: "Context menu to dump and download a server's emojis.",
|
description: "Context menu to dump and download a server's emojis.",
|
||||||
authors: [EquicordDevs.Cortex, Devs.Samwich, EquicordDevs.Woosh],
|
authors: [EquicordDevs.Cortex, Devs.Samwich, EquicordDevs.Woosh],
|
||||||
start() {
|
start() {
|
||||||
|
|
|
@ -344,6 +344,7 @@ function QrModal(props: ModalProps) {
|
||||||
stream = str;
|
stream = str;
|
||||||
video.srcObject = str;
|
video.srcObject = str;
|
||||||
video.addEventListener("loadedmetadata", () => {
|
video.addEventListener("loadedmetadata", () => {
|
||||||
|
if (stopped) return stop(str);
|
||||||
video.play();
|
video.play();
|
||||||
modalProps.current.setPreview(video);
|
modalProps.current.setPreview(video);
|
||||||
snapshot();
|
snapshot();
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { openNewPluginsModal } from "./NewPluginsModal";
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "NewPluginsManager",
|
name: "NewPluginsManager",
|
||||||
description: "Utility that notifies you when new plugins are added to Vencord",
|
description: "Utility that notifies you when new plugins are added to Equicord",
|
||||||
authors: [Devs.Sqaaakoi],
|
authors: [Devs.Sqaaakoi],
|
||||||
flux: {
|
flux: {
|
||||||
async POST_CONNECTION_OPEN() {
|
async POST_CONNECTION_OPEN() {
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { migratePluginSettings } from "@api/Settings";
|
||||||
import { EquicordDevs } from "@utils/constants";
|
import { EquicordDevs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
|
migratePluginSettings("NoAppsAllowed", "noAppsAllowed");
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "noAppsAllowed",
|
name: "NoAppsAllowed",
|
||||||
description: "returns the bot's tag :skulk:",
|
description: "returns the bot's tag :skulk:",
|
||||||
authors: [EquicordDevs.kvba],
|
authors: [EquicordDevs.kvba],
|
||||||
|
|
||||||
|
|
149
src/equicordplugins/stickerBlocker/index.tsx
Normal file
149
src/equicordplugins/stickerBlocker/index.tsx
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
|
import { DataStore } from "@api/index";
|
||||||
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { Button, Menu } from "@webpack/common";
|
||||||
|
import React, { ReactNode } from "react";
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
showGif: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Whether to show a snazzy cat gif",
|
||||||
|
default: true,
|
||||||
|
restartNeeded: true
|
||||||
|
},
|
||||||
|
showMessage: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Whether to show a message detailing which id was blocked",
|
||||||
|
default: false,
|
||||||
|
restartNeeded: true
|
||||||
|
},
|
||||||
|
showButton: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Whether to show a button to unblock the gif",
|
||||||
|
default: true,
|
||||||
|
restartNeeded: true
|
||||||
|
},
|
||||||
|
blockedStickers: {
|
||||||
|
type: OptionType.STRING,
|
||||||
|
description: "The list of blocked sticker IDs (don't edit unless you know what you're doing)",
|
||||||
|
default: ""
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function blockedComponentRender(sticker) {
|
||||||
|
const { showGif, showMessage, showButton } = settings.store;
|
||||||
|
const elements = [] as ReactNode[];
|
||||||
|
|
||||||
|
if (showGif) {
|
||||||
|
elements.push(
|
||||||
|
<img key="gif" src="https://files.catbox.moe/bdsc58.gif" style={{ width: "160px", borderRadius: "20px" }} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showMessage) {
|
||||||
|
elements.push(
|
||||||
|
<div key="message" id="message-content-1205482612316184657" className={"markup_a7e664 messageContent__21e69"}><span>Blocked Sticker. ID: {sticker.id}, NAME: {sticker.name}</span></div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showButton) {
|
||||||
|
elements.push(
|
||||||
|
<Button key="button" onClick={() => toggleBlock(sticker.id)} color={Button.Colors.RED}>Unblock {(showMessage) ? "" : sticker.name}</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{elements}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => {
|
||||||
|
const { favoriteableId, favoriteableType } = props ?? {};
|
||||||
|
|
||||||
|
if (!favoriteableId) return;
|
||||||
|
|
||||||
|
const menuItem = (() => {
|
||||||
|
switch (favoriteableType) {
|
||||||
|
case "sticker":
|
||||||
|
const sticker = props.message.stickerItems.find(s => s.id === favoriteableId);
|
||||||
|
if (sticker?.format_type === 3 /* LOTTIE */) return;
|
||||||
|
|
||||||
|
return buildMenuItem(favoriteableId);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (menuItem)
|
||||||
|
findGroupChildrenByChildId("copy-link", children)?.push(menuItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { target: HTMLElement; }) => {
|
||||||
|
const { id, type } = props?.target?.dataset ?? {};
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
if (type === "sticker" && !props.target.className?.includes("lottieCanvas")) {
|
||||||
|
children.push(buildMenuItem(id));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function buildMenuItem(name) {
|
||||||
|
return (
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="add-sticker-block"
|
||||||
|
key="add-sticker-block"
|
||||||
|
label={(isStickerBlocked(name)) ? "Unblock Sticker" : "Block Sticker"}
|
||||||
|
action={() => toggleBlock(name)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleBlock(name) {
|
||||||
|
if (settings.store.blockedStickers === undefined || settings.store.blockedStickers == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const excepted = isStickerBlocked(name);
|
||||||
|
if (excepted) {
|
||||||
|
settings.store.blockedStickers = settings.store.blockedStickers.split(", ").filter(item => item !== name).join(", ");
|
||||||
|
} else {
|
||||||
|
settings.store.blockedStickers = settings.store.blockedStickers.split(", ").concat(name).join(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function isStickerBlocked(name) {
|
||||||
|
if (settings.store.blockedStickers === undefined || settings.store.blockedStickers == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return settings.store.blockedStickers.split(", ").includes(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "StickerBlocker",
|
||||||
|
description: "Allows you to block stickers from being displayed.",
|
||||||
|
authors: [Devs.Samwich],
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: /\i\.\i\.STICKER_MESSAGE/,
|
||||||
|
replacement: {
|
||||||
|
match: /}\),\(null!=\i\?\i:(\i)\)\.name]}\);/,
|
||||||
|
replace: "$& if(Vencord.Settings.plugins.StickerBlocker.blockedStickers.split(\", \").includes($1.id)) { return($self.blockedComponent($1)) }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
contextMenus: {
|
||||||
|
"message": messageContextMenuPatch,
|
||||||
|
"expression-picker": expressionPickerPatch,
|
||||||
|
},
|
||||||
|
start() {
|
||||||
|
DataStore.createStore("StickerBlocker", "data");
|
||||||
|
},
|
||||||
|
blockedComponent: ErrorBoundary.wrap(blockedComponentRender, { fallback: () => <p style={{ color: "red" }}>Failed to render :(</p> }),
|
||||||
|
settings,
|
||||||
|
});
|
|
@ -15,7 +15,7 @@ const rootTitle = { base: null as string | null };
|
||||||
export const settings = definePluginSettings({
|
export const settings = definePluginSettings({
|
||||||
title: {
|
title: {
|
||||||
type: OptionType.STRING,
|
type: OptionType.STRING,
|
||||||
default: "Vencord",
|
default: "Equicord",
|
||||||
description: "Window title prefix",
|
description: "Window title prefix",
|
||||||
onChange: setTitle,
|
onChange: setTitle,
|
||||||
},
|
},
|
||||||
|
|
|
@ -241,7 +241,7 @@ async function createActivity(): Promise<Activity | undefined> {
|
||||||
|
|
||||||
let { type } = settings.store;
|
let { type } = settings.store;
|
||||||
|
|
||||||
let appName = "Vencord";
|
let appName = "Equicord";
|
||||||
let details = "";
|
let details = "";
|
||||||
let state = "";
|
let state = "";
|
||||||
let imageBig = "";
|
let imageBig = "";
|
||||||
|
|
|
@ -53,6 +53,31 @@ if (IS_VESKTOP || !IS_VANILLA) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
protocol.registerFileProtocol("equicord", ({ url: unsafeUrl }, cb) => {
|
||||||
|
let url = unsafeUrl.slice("equicord://".length);
|
||||||
|
if (url.endsWith("/")) url = url.slice(0, -1);
|
||||||
|
if (url.startsWith("/themes/")) {
|
||||||
|
const theme = url.slice("/themes/".length);
|
||||||
|
const safeUrl = ensureSafePath(THEMES_DIR, theme);
|
||||||
|
if (!safeUrl) {
|
||||||
|
cb({ statusCode: 403 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cb(safeUrl.replace(/\?v=\d+$/, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (url) {
|
||||||
|
case "renderer.js.map":
|
||||||
|
case "preload.js.map":
|
||||||
|
case "patcher.js.map":
|
||||||
|
case "main.js.map":
|
||||||
|
cb(join(__dirname, url));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cb({ statusCode: 403 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (RendererSettings.store.enableReactDevtools)
|
if (RendererSettings.store.enableReactDevtools)
|
||||||
installExt("fmkadmapgofadopljbjfkapdkoienihi")
|
installExt("fmkadmapgofadopljbjfkapdkoienihi")
|
||||||
|
|
|
@ -162,13 +162,13 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
name: "equicord-debug",
|
name: "equicord-debug",
|
||||||
description: "Send Equicord debug info",
|
description: "Send Equicord debug info",
|
||||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
||||||
execute: async () => ({ content: await generateDebugInfoMessage() })
|
execute: async () => ({ content: await generateDebugInfoMessage() })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "equicord-plugins",
|
name: "equicord-plugins",
|
||||||
description: "Send Equicord plugin list",
|
description: "Send Equicord plugin list",
|
||||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
||||||
execute: () => ({ content: generatePluginList() })
|
execute: () => ({ content: generatePluginList() })
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -254,7 +254,7 @@ export default definePlugin({
|
||||||
|
|
||||||
ContributorDmWarningCard: ErrorBoundary.wrap(({ userId }) => {
|
ContributorDmWarningCard: ErrorBoundary.wrap(({ userId }) => {
|
||||||
if (!isPluginDev(userId) || !isEquicordPluginDev(userId)) return null;
|
if (!isPluginDev(userId) || !isEquicordPluginDev(userId)) return null;
|
||||||
if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id)) return null;
|
if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id)) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={`vc-plugins-restart-card ${Margins.top8}`}>
|
<Card className={`vc-plugins-restart-card ${Margins.top8}`}>
|
||||||
|
|
|
@ -30,7 +30,7 @@ function onPickColor(color: number) {
|
||||||
updateColorVars(hexColor);
|
updateColorVars(hexColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE",settings:{useSystemTheme:null!=');
|
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"===');
|
||||||
|
|
||||||
function setTheme(theme: string) {
|
function setTheme(theme: string) {
|
||||||
saveClientTheme({ theme });
|
saveClientTheme({ theme });
|
||||||
|
|
|
@ -57,7 +57,7 @@ function decode(bio: string): Array<number> | null {
|
||||||
if (bio == null) return null;
|
if (bio == null) return null;
|
||||||
|
|
||||||
const colorString = bio.match(
|
const colorString = bio.match(
|
||||||
/\u{e005b}\u{e0023}([\u{e0061}-\u{e0066}\u{e0041}-\u{e0046}\u{e0030}-\u{e0039}]{6})\u{e002c}\u{e0023}([\u{e0061}-\u{e0066}\u{e0041}-\u{e0046}\u{e0030}-\u{e0039}]{6})\u{e005d}/u,
|
/\u{e005b}\u{e0023}([\u{e0061}-\u{e0066}\u{e0041}-\u{e0046}\u{e0030}-\u{e0039}]{1,6})\u{e002c}\u{e0023}([\u{e0061}-\u{e0066}\u{e0041}-\u{e0046}\u{e0030}-\u{e0039}]{1,6})\u{e005d}/u,
|
||||||
);
|
);
|
||||||
if (colorString != null) {
|
if (colorString != null) {
|
||||||
const parsed = [...colorString[0]]
|
const parsed = [...colorString[0]]
|
||||||
|
|
|
@ -171,7 +171,7 @@ export default definePlugin({
|
||||||
find: ".handleImageLoad)",
|
find: ".handleImageLoad)",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /dataSafeSrc:\i,children:/,
|
match: /placeholderVersion:\i,(?=.{0,50}children:)/,
|
||||||
replace: "...$self.makeProps(this),$&"
|
replace: "...$self.makeProps(this),$&"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings, migratePluginSettings, Settings } from "@api/Settings";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ const settings = definePluginSettings({
|
||||||
},
|
},
|
||||||
onChange: () => {
|
onChange: () => {
|
||||||
// note: cant call the start() function from here. so i just copy pasted it (This was pointed out in the last commit i made. So this is to just clear stuff up for any future devs that work on this :D )
|
// note: cant call the start() function from here. so i just copy pasted it (This was pointed out in the last commit i made. So this is to just clear stuff up for any future devs that work on this :D )
|
||||||
if (Settings.plugins.oneko.enabled) {
|
if (Settings.plugins.Oneko.enabled) {
|
||||||
document.getElementById("oneko")?.remove();
|
document.getElementById("oneko")?.remove();
|
||||||
fetch("https://raw.githubusercontent.com/adryd325/oneko.js/8fa8a1864aa71cd7a794d58bc139e755e96a236c/oneko.js")
|
fetch("https://raw.githubusercontent.com/adryd325/oneko.js/8fa8a1864aa71cd7a794d58bc139e755e96a236c/oneko.js")
|
||||||
.then(x => x.text())
|
.then(x => x.text())
|
||||||
|
@ -45,8 +45,9 @@ const settings = definePluginSettings({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migratePluginSettings("Oneko", "oneko");
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "oneko",
|
name: "Oneko",
|
||||||
description: "cat follow mouse (real)",
|
description: "cat follow mouse (real)",
|
||||||
// Listing adryd here because this literally just evals her script
|
// Listing adryd here because this literally just evals her script
|
||||||
authors: [Devs.Ven, Devs.adryd],
|
authors: [Devs.Ven, Devs.adryd],
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: '"account";',
|
find: "this.isCopiedStreakGodlike",
|
||||||
replacement: {
|
replacement: {
|
||||||
// react.jsx)(AccountPanel, { ..., showTaglessAccountPanel: blah })
|
// react.jsx)(AccountPanel, { ..., showTaglessAccountPanel: blah })
|
||||||
match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?userTag:\i,hidePrivateData:)/,
|
match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?userTag:\i,hidePrivateData:)/,
|
||||||
|
|
|
@ -189,7 +189,8 @@ export default definePlugin({
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /avatarSrc:(\i),eventHandlers:(\i).+?"div",{...\2,/,
|
match: /avatarSrc:(\i),eventHandlers:(\i).+?"div",{...\2,/,
|
||||||
replace: "$&style:{cursor:\"pointer\"},onClick:()=>{$self.openImage($1)},"
|
replace: "$&style:{cursor:\"pointer\"},onClick:()=>{$self.openImage($1)},"
|
||||||
}
|
},
|
||||||
|
all: true
|
||||||
},
|
},
|
||||||
// Old Profiles Modal pfp
|
// Old Profiles Modal pfp
|
||||||
{
|
{
|
||||||
|
|
|
@ -271,7 +271,7 @@ function sendMsgNotif(titleString: string, content: string, message: Message) {
|
||||||
content: content,
|
content: content,
|
||||||
useBase64Icon: true,
|
useBase64Icon: true,
|
||||||
icon: result,
|
icon: result,
|
||||||
sourceApp: "Vencord"
|
sourceApp: "Equicord"
|
||||||
};
|
};
|
||||||
Native.sendToOverlay(msgData);
|
Native.sendToOverlay(msgData);
|
||||||
});
|
});
|
||||||
|
@ -290,7 +290,7 @@ function sendOtherNotif(content: string, titleString: string) {
|
||||||
content: content,
|
content: content,
|
||||||
useBase64Icon: false,
|
useBase64Icon: false,
|
||||||
icon: null,
|
icon: null,
|
||||||
sourceApp: "Vencord"
|
sourceApp: "Equicord"
|
||||||
};
|
};
|
||||||
Native.sendToOverlay(msgData);
|
Native.sendToOverlay(msgData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,7 +535,11 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
Antti: {
|
Antti: {
|
||||||
name: "Antti",
|
name: "Antti",
|
||||||
id: 312974985876471810n
|
id: 312974985876471810n
|
||||||
}
|
},
|
||||||
|
Joona: {
|
||||||
|
name: "Joona",
|
||||||
|
id: 297410829589020673n
|
||||||
|
},
|
||||||
} satisfies Record<string, Dev>);
|
} satisfies Record<string, Dev>);
|
||||||
|
|
||||||
export const EquicordDevs = Object.freeze({
|
export const EquicordDevs = Object.freeze({
|
||||||
|
@ -707,6 +711,10 @@ export const EquicordDevs = Object.freeze({
|
||||||
name: "Joona",
|
name: "Joona",
|
||||||
id: 297410829589020673n
|
id: 297410829589020673n
|
||||||
},
|
},
|
||||||
|
SimplyData: {
|
||||||
|
name: "SimplyData",
|
||||||
|
id: 301494563514613762n
|
||||||
|
},
|
||||||
} satisfies Record<string, Dev>);
|
} satisfies Record<string, Dev>);
|
||||||
|
|
||||||
export const SuncordDevs = /* #__PURE__*/ Object.freeze({
|
export const SuncordDevs = /* #__PURE__*/ Object.freeze({
|
||||||
|
|
|
@ -68,7 +68,7 @@ export async function compileUsercss(fileName: string) {
|
||||||
const preprocessorFn = preprocessors[preprocessor];
|
const preprocessorFn = preprocessors[preprocessor];
|
||||||
|
|
||||||
if (!preprocessorFn) {
|
if (!preprocessorFn) {
|
||||||
UserCSSLogger.error("File", fileName, "requires preprocessor", preprocessor, "which isn't known to Vencord");
|
UserCSSLogger.error("File", fileName, "requires preprocessor", preprocessor, "which isn't known to Equicord");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue