mirror of
https://github.com/Vendicated/Vencord.git
synced 2024-09-20 06:30:35 +00:00
Merge branch 'dev' into NotesSearcher
This commit is contained in:
commit
6b88d4e4bd
17 changed files with 406 additions and 205 deletions
|
@ -2,23 +2,22 @@ if (typeof browser === "undefined") {
|
|||
var browser = chrome;
|
||||
}
|
||||
|
||||
const script = document.createElement("script");
|
||||
script.src = browser.runtime.getURL("dist/Vencord.js");
|
||||
script.id = "vencord-script";
|
||||
Object.assign(script.dataset, {
|
||||
extensionBaseUrl: browser.runtime.getURL(""),
|
||||
version: browser.runtime.getManifest().version
|
||||
});
|
||||
|
||||
const style = document.createElement("link");
|
||||
style.type = "text/css";
|
||||
style.rel = "stylesheet";
|
||||
style.href = browser.runtime.getURL("dist/Vencord.css");
|
||||
|
||||
document.documentElement.append(script);
|
||||
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
() => document.documentElement.append(style),
|
||||
() => {
|
||||
document.documentElement.append(style);
|
||||
window.postMessage({
|
||||
type: "vencord:meta",
|
||||
meta: {
|
||||
EXTENSION_VERSION: browser.runtime.getManifest().version,
|
||||
EXTENSION_BASE_URL: browser.runtime.getURL(""),
|
||||
}
|
||||
});
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
|
|
@ -22,7 +22,15 @@
|
|||
"run_at": "document_start",
|
||||
"matches": ["*://*.discord.com/*"],
|
||||
"js": ["content.js"],
|
||||
"all_frames": true
|
||||
"all_frames": true,
|
||||
"world": "ISOLATED"
|
||||
},
|
||||
{
|
||||
"run_at": "document_start",
|
||||
"matches": ["*://*.discord.com/*"],
|
||||
"js": ["dist/Vencord.js"],
|
||||
"all_frames": true,
|
||||
"world": "MAIN"
|
||||
}
|
||||
],
|
||||
|
||||
|
|
|
@ -22,7 +22,15 @@
|
|||
"run_at": "document_start",
|
||||
"matches": ["*://*.discord.com/*"],
|
||||
"js": ["content.js"],
|
||||
"all_frames": true
|
||||
"all_frames": true,
|
||||
"world": "ISOLATED"
|
||||
},
|
||||
{
|
||||
"run_at": "document_start",
|
||||
"matches": ["*://*.discord.com/*"],
|
||||
"js": ["dist/Vencord.js"],
|
||||
"all_frames": true,
|
||||
"world": "MAIN"
|
||||
}
|
||||
],
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "vencord",
|
||||
"private": "true",
|
||||
"version": "1.9.0",
|
||||
"version": "1.9.1",
|
||||
"description": "The cutest Discord client mod",
|
||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||
"bugs": {
|
||||
|
@ -43,7 +43,7 @@
|
|||
"eslint-plugin-simple-header": "^1.0.2",
|
||||
"fflate": "^0.7.4",
|
||||
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
|
||||
"monaco-editor": "^0.43.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"nanoid": "^4.0.2",
|
||||
"virtual-merge": "^1.0.1"
|
||||
},
|
||||
|
|
|
@ -35,8 +35,8 @@ importers:
|
|||
specifier: github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3
|
||||
version: https://codeload.github.com/mattdesl/gifenc/tar.gz/64842fca317b112a8590f8fef2bf3825da8f6fe3
|
||||
monaco-editor:
|
||||
specifier: ^0.43.0
|
||||
version: 0.43.0
|
||||
specifier: ^0.50.0
|
||||
version: 0.50.0
|
||||
nanoid:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
|
@ -1531,6 +1531,10 @@ packages:
|
|||
is-core-module@2.13.1:
|
||||
resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
|
||||
|
||||
is-core-module@2.14.0:
|
||||
resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-data-descriptor@0.1.4:
|
||||
resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -1791,8 +1795,8 @@ packages:
|
|||
moment@2.29.4:
|
||||
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
|
||||
|
||||
monaco-editor@0.43.0:
|
||||
resolution: {integrity: sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q==}
|
||||
monaco-editor@0.50.0:
|
||||
resolution: {integrity: sha512-8CclLCmrRRh+sul7C08BmPBP3P8wVWfBHomsTcndxg5NRCEPfu/mc2AGU8k37ajjDVXcXFc12ORAMUkmk+lkFA==}
|
||||
|
||||
ms@2.0.0:
|
||||
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
|
||||
|
@ -3463,7 +3467,7 @@ snapshots:
|
|||
eslint-import-resolver-node@0.3.9:
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
is-core-module: 2.13.1
|
||||
is-core-module: 2.14.0
|
||||
resolve: 1.22.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -3490,7 +3494,7 @@ snapshots:
|
|||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.59.1(eslint@8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4))(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.46.0(patch_hash=xm46kqcmdgzlmm4aifkfpxaho4))
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.13.1
|
||||
is-core-module: 2.14.0
|
||||
is-glob: 4.0.3
|
||||
minimatch: 3.1.2
|
||||
object.fromentries: 2.0.8
|
||||
|
@ -3934,6 +3938,10 @@ snapshots:
|
|||
dependencies:
|
||||
hasown: 2.0.2
|
||||
|
||||
is-core-module@2.14.0:
|
||||
dependencies:
|
||||
hasown: 2.0.2
|
||||
|
||||
is-data-descriptor@0.1.4:
|
||||
dependencies:
|
||||
kind-of: 3.2.2
|
||||
|
@ -4169,7 +4177,7 @@ snapshots:
|
|||
|
||||
moment@2.29.4: {}
|
||||
|
||||
monaco-editor@0.43.0: {}
|
||||
monaco-editor@0.50.0: {}
|
||||
|
||||
ms@2.0.0: {}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<title>Vencord QuickCSS Editor</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.40.0/min/vs/editor/editor.main.min.css"
|
||||
integrity="sha512-MOoQ02h80hklccfLrXFYkCzG+WVjORflOp9Zp8dltiaRP+35LYnO4LKOklR64oMGfGgJDLO8WJpkM1o5gZXYZQ=="
|
||||
href="https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs/editor/editor.main.css"
|
||||
integrity="sha256-tiJPQ2O04z/pZ/AwdyIghrOMzewf+PIvEl1YKbQvsZk="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
|
@ -29,8 +29,8 @@
|
|||
<body>
|
||||
<div id="container"></div>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.40.0/min/vs/loader.min.js"
|
||||
integrity="sha512-QzMpXeCPciAHP4wbYlV2PYgrQcaEkDQUjzkPU4xnjyVSD9T36/udamxtNBqb4qK4/bMQMPZ8ayrBe9hrGdBFjQ=="
|
||||
src="https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs/loader.js"
|
||||
integrity="sha256-KcU48TGr84r7unF7J5IgBo95aeVrEbrGe04S7TcFUjs="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
|
@ -38,7 +38,7 @@
|
|||
<script>
|
||||
require.config({
|
||||
paths: {
|
||||
vs: "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.40.0/min/vs",
|
||||
vs: "https://cdn.jsdelivr.net/npm/monaco-editor@0.50.0/min/vs",
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -16,24 +16,33 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { addAccessory } from "@api/MessageAccessories";
|
||||
import { getUserSettingLazy } from "@api/UserSettings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Flex } from "@components/Flex";
|
||||
import { Link } from "@components/Link";
|
||||
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
|
||||
import { Devs, SUPPORT_CHANNEL_ID } from "@utils/constants";
|
||||
import { sendMessage } from "@utils/discord";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { isPluginDev } from "@utils/misc";
|
||||
import { isPluginDev, tryOrElse } from "@utils/misc";
|
||||
import { relaunch } from "@utils/native";
|
||||
import { onlyOnce } from "@utils/onlyOnce";
|
||||
import { makeCodeblock } from "@utils/text";
|
||||
import definePlugin from "@utils/types";
|
||||
import { isOutdated, update } from "@utils/updater";
|
||||
import { Alerts, Card, ChannelStore, Forms, GuildMemberStore, NavigationRouter, Parser, RelationshipStore, UserStore } from "@webpack/common";
|
||||
import { checkForUpdates, isOutdated, update } from "@utils/updater";
|
||||
import { Alerts, Button, Card, ChannelStore, Forms, GuildMemberStore, Parser, RelationshipStore, showToast, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
import gitHash from "~git-hash";
|
||||
import plugins from "~plugins";
|
||||
import plugins, { PluginMeta } from "~plugins";
|
||||
|
||||
import settings from "./settings";
|
||||
|
||||
const VENCORD_GUILD_ID = "1015060230222131221";
|
||||
const VENBOT_USER_ID = "1017176847865352332";
|
||||
const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
|
||||
const CodeBlockRe = /```js\n(.+?)```/s;
|
||||
|
||||
const AllowedChannelIds = [
|
||||
SUPPORT_CHANNEL_ID,
|
||||
|
@ -47,12 +56,88 @@ const TrustedRolesIds = [
|
|||
"1042507929485586532", // donor
|
||||
];
|
||||
|
||||
const AsyncFunction = async function () { }.constructor;
|
||||
|
||||
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
|
||||
|
||||
async function forceUpdate() {
|
||||
const outdated = await checkForUpdates();
|
||||
if (outdated) {
|
||||
await update();
|
||||
relaunch();
|
||||
}
|
||||
|
||||
return outdated;
|
||||
}
|
||||
|
||||
async function generateDebugInfoMessage() {
|
||||
const { RELEASE_CHANNEL } = window.GLOBAL_ENV;
|
||||
|
||||
const client = (() => {
|
||||
if (IS_DISCORD_DESKTOP) return `Discord Desktop v${DiscordNative.app.getVersion()}`;
|
||||
if (IS_VESKTOP) return `Vesktop v${VesktopNative.app.getVersion()}`;
|
||||
if ("armcord" in window) return `ArmCord v${window.armcord.version}`;
|
||||
|
||||
// @ts-expect-error
|
||||
const name = typeof unsafeWindow !== "undefined" ? "UserScript" : "Web";
|
||||
return `${name} (${navigator.userAgent})`;
|
||||
})();
|
||||
|
||||
const info = {
|
||||
Vencord:
|
||||
`v${VERSION} • [${gitHash}](<https://github.com/Vendicated/Vencord/commit/${gitHash}>)` +
|
||||
`${settings.additionalInfo} - ${Intl.DateTimeFormat("en-GB", { dateStyle: "medium" }).format(BUILD_TIMESTAMP)}`,
|
||||
Client: `${RELEASE_CHANNEL} ~ ${client}`,
|
||||
Platform: window.navigator.platform
|
||||
};
|
||||
|
||||
if (IS_DISCORD_DESKTOP) {
|
||||
info["Last Crash Reason"] = (await tryOrElse(() => DiscordNative.processUtils.getLastCrash(), undefined))?.rendererCrashReason ?? "N/A";
|
||||
}
|
||||
|
||||
const commonIssues = {
|
||||
"NoRPC enabled": Vencord.Plugins.isPluginEnabled("NoRPC"),
|
||||
"Activity Sharing disabled": tryOrElse(() => !ShowCurrentGame.getSetting(), false),
|
||||
"Vencord DevBuild": !IS_STANDALONE,
|
||||
"Has UserPlugins": Object.values(PluginMeta).some(m => m.userPlugin),
|
||||
"More than two weeks out of date": BUILD_TIMESTAMP < Date.now() - 12096e5,
|
||||
};
|
||||
|
||||
let content = `>>> ${Object.entries(info).map(([k, v]) => `**${k}**: ${v}`).join("\n")}`;
|
||||
content += "\n" + Object.entries(commonIssues)
|
||||
.filter(([, v]) => v).map(([k]) => `⚠️ ${k}`)
|
||||
.join("\n");
|
||||
|
||||
return content.trim();
|
||||
}
|
||||
|
||||
function generatePluginList() {
|
||||
const isApiPlugin = (plugin: string) => plugin.endsWith("API") || plugins[plugin].required;
|
||||
|
||||
const enabledPlugins = Object.keys(plugins)
|
||||
.filter(p => Vencord.Plugins.isPluginEnabled(p) && !isApiPlugin(p));
|
||||
|
||||
const enabledStockPlugins = enabledPlugins.filter(p => !PluginMeta[p].userPlugin);
|
||||
const enabledUserPlugins = enabledPlugins.filter(p => PluginMeta[p].userPlugin);
|
||||
|
||||
|
||||
let content = `**Enabled Plugins (${enabledStockPlugins.length}):**\n${makeCodeblock(enabledStockPlugins.join(", "))}`;
|
||||
|
||||
if (enabledUserPlugins.length) {
|
||||
content += `**Enabled UserPlugins (${enabledUserPlugins.length}):**\n${makeCodeblock(enabledUserPlugins.join(", "))}`;
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
const checkForUpdatesOnce = onlyOnce(checkForUpdates);
|
||||
|
||||
export default definePlugin({
|
||||
name: "SupportHelper",
|
||||
required: true,
|
||||
description: "Helps us provide support to you",
|
||||
authors: [Devs.Ven],
|
||||
dependencies: ["CommandsAPI"],
|
||||
dependencies: ["CommandsAPI", "UserSettingsAPI", "MessageAccessoriesAPI"],
|
||||
|
||||
patches: [{
|
||||
find: ".BEGINNING_DM.format",
|
||||
|
@ -62,51 +147,20 @@ export default definePlugin({
|
|||
}
|
||||
}],
|
||||
|
||||
commands: [{
|
||||
name: "vencord-debug",
|
||||
description: "Send Vencord Debug info",
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
||||
async execute() {
|
||||
const { RELEASE_CHANNEL } = window.GLOBAL_ENV;
|
||||
|
||||
const client = (() => {
|
||||
if (IS_DISCORD_DESKTOP) return `Discord Desktop v${DiscordNative.app.getVersion()}`;
|
||||
if (IS_VESKTOP) return `Vesktop v${VesktopNative.app.getVersion()}`;
|
||||
if ("armcord" in window) return `ArmCord v${window.armcord.version}`;
|
||||
|
||||
// @ts-expect-error
|
||||
const name = typeof unsafeWindow !== "undefined" ? "UserScript" : "Web";
|
||||
return `${name} (${navigator.userAgent})`;
|
||||
})();
|
||||
|
||||
const isApiPlugin = (plugin: string) => plugin.endsWith("API") || plugins[plugin].required;
|
||||
|
||||
const enabledPlugins = Object.keys(plugins).filter(p => Vencord.Plugins.isPluginEnabled(p) && !isApiPlugin(p));
|
||||
|
||||
const info = {
|
||||
Vencord:
|
||||
`v${VERSION} • [${gitHash}](<https://github.com/Vendicated/Vencord/commit/${gitHash}>)` +
|
||||
`${settings.additionalInfo} - ${Intl.DateTimeFormat("en-GB", { dateStyle: "medium" }).format(BUILD_TIMESTAMP)}`,
|
||||
Client: `${RELEASE_CHANNEL} ~ ${client}`,
|
||||
Platform: window.navigator.platform
|
||||
};
|
||||
|
||||
if (IS_DISCORD_DESKTOP) {
|
||||
info["Last Crash Reason"] = (await DiscordNative.processUtils.getLastCrash())?.rendererCrashReason ?? "N/A";
|
||||
}
|
||||
|
||||
const debugInfo = `
|
||||
>>> ${Object.entries(info).map(([k, v]) => `**${k}**: ${v}`).join("\n")}
|
||||
|
||||
Enabled Plugins (${enabledPlugins.length}):
|
||||
${makeCodeblock(enabledPlugins.join(", "))}
|
||||
`;
|
||||
|
||||
return {
|
||||
content: debugInfo.trim().replaceAll("```\n", "```")
|
||||
};
|
||||
commands: [
|
||||
{
|
||||
name: "vencord-debug",
|
||||
description: "Send Vencord debug info",
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
||||
execute: async () => ({ content: await generateDebugInfoMessage() })
|
||||
},
|
||||
{
|
||||
name: "vencord-plugins",
|
||||
description: "Send Vencord plugin list",
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
||||
execute: () => ({ content: generatePluginList() })
|
||||
}
|
||||
}],
|
||||
],
|
||||
|
||||
flux: {
|
||||
async CHANNEL_SELECT({ channelId }) {
|
||||
|
@ -115,24 +169,25 @@ ${makeCodeblock(enabledPlugins.join(", "))}
|
|||
const selfId = UserStore.getCurrentUser()?.id;
|
||||
if (!selfId || isPluginDev(selfId)) return;
|
||||
|
||||
if (isOutdated) {
|
||||
return Alerts.show({
|
||||
title: "Hold on!",
|
||||
body: <div>
|
||||
<Forms.FormText>You are using an outdated version of Vencord! Chances are, your issue is already fixed.</Forms.FormText>
|
||||
<Forms.FormText className={Margins.top8}>
|
||||
Please first update before asking for support!
|
||||
</Forms.FormText>
|
||||
</div>,
|
||||
onCancel: () => openUpdaterModal!(),
|
||||
cancelText: "View Updates",
|
||||
confirmText: "Update & Restart Now",
|
||||
async onConfirm() {
|
||||
await update();
|
||||
relaunch();
|
||||
},
|
||||
secondaryConfirmText: "I know what I'm doing or I can't update"
|
||||
});
|
||||
if (!IS_UPDATER_DISABLED) {
|
||||
await checkForUpdatesOnce().catch(() => { });
|
||||
|
||||
if (isOutdated) {
|
||||
return Alerts.show({
|
||||
title: "Hold on!",
|
||||
body: <div>
|
||||
<Forms.FormText>You are using an outdated version of Vencord! Chances are, your issue is already fixed.</Forms.FormText>
|
||||
<Forms.FormText className={Margins.top8}>
|
||||
Please first update before asking for support!
|
||||
</Forms.FormText>
|
||||
</div>,
|
||||
onCancel: () => openUpdaterModal!(),
|
||||
cancelText: "View Updates",
|
||||
confirmText: "Update & Restart Now",
|
||||
onConfirm: forceUpdate,
|
||||
secondaryConfirmText: "I know what I'm doing or I can't update"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore outdated type
|
||||
|
@ -148,8 +203,7 @@ ${makeCodeblock(enabledPlugins.join(", "))}
|
|||
Please either switch to an <Link href="https://vencord.dev/download">officially supported version of Vencord</Link>, or
|
||||
contact your package maintainer for support instead.
|
||||
</Forms.FormText>
|
||||
</div>,
|
||||
onCloseCallback: () => setTimeout(() => NavigationRouter.back(), 50)
|
||||
</div>
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -163,8 +217,7 @@ ${makeCodeblock(enabledPlugins.join(", "))}
|
|||
Please either switch to an <Link href="https://vencord.dev/download">officially supported version of Vencord</Link>, or
|
||||
contact your package maintainer for support instead.
|
||||
</Forms.FormText>
|
||||
</div>,
|
||||
onCloseCallback: () => setTimeout(() => NavigationRouter.back(), 50)
|
||||
</div>
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +225,7 @@ ${makeCodeblock(enabledPlugins.join(", "))}
|
|||
|
||||
ContributorDmWarningCard: ErrorBoundary.wrap(({ userId }) => {
|
||||
if (!isPluginDev(userId)) return null;
|
||||
if (RelationshipStore.isFriend(userId)) return null;
|
||||
if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id)) return null;
|
||||
|
||||
return (
|
||||
<Card className={`vc-plugins-restart-card ${Margins.top8}`}>
|
||||
|
@ -182,5 +235,86 @@ ${makeCodeblock(enabledPlugins.join(", "))}
|
|||
{!ChannelStore.getChannel(SUPPORT_CHANNEL_ID) && " (Click the link to join)"}
|
||||
</Card>
|
||||
);
|
||||
}, { noop: true })
|
||||
}, { noop: true }),
|
||||
|
||||
start() {
|
||||
addAccessory("vencord-debug", props => {
|
||||
const buttons = [] as JSX.Element[];
|
||||
|
||||
const shouldAddUpdateButton =
|
||||
!IS_UPDATER_DISABLED
|
||||
&& (
|
||||
(props.channel.id === KNOWN_ISSUES_CHANNEL_ID) ||
|
||||
(props.channel.id === SUPPORT_CHANNEL_ID && props.message.author.id === VENBOT_USER_ID)
|
||||
)
|
||||
&& props.message.content?.includes("update");
|
||||
|
||||
if (shouldAddUpdateButton) {
|
||||
buttons.push(
|
||||
<Button
|
||||
key="vc-update"
|
||||
color={Button.Colors.GREEN}
|
||||
onClick={async () => {
|
||||
try {
|
||||
if (await forceUpdate())
|
||||
showToast("Success! Restarting...", Toasts.Type.SUCCESS);
|
||||
else
|
||||
showToast("Already up to date!", Toasts.Type.MESSAGE);
|
||||
} catch (e) {
|
||||
new Logger(this.name).error("Error while updating:", e);
|
||||
showToast("Failed to update :(", Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Update Now
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
if (props.channel.id === SUPPORT_CHANNEL_ID) {
|
||||
if (props.message.content.includes("/vencord-debug") || props.message.content.includes("/vencord-plugins")) {
|
||||
buttons.push(
|
||||
<Button
|
||||
key="vc-dbg"
|
||||
onClick={async () => sendMessage(props.channel.id, { content: await generateDebugInfoMessage() })}
|
||||
>
|
||||
Run /vencord-debug
|
||||
</Button>,
|
||||
<Button
|
||||
key="vc-plg-list"
|
||||
onClick={async () => sendMessage(props.channel.id, { content: generatePluginList() })}
|
||||
>
|
||||
Run /vencord-plugins
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
if (props.message.author.id === VENBOT_USER_ID) {
|
||||
const match = CodeBlockRe.exec(props.message.content || props.message.embeds[0]?.rawDescription || "");
|
||||
if (match) {
|
||||
buttons.push(
|
||||
<Button
|
||||
key="vc-run-snippet"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await AsyncFunction(match[1])();
|
||||
showToast("Success!", Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger(this.name).error("Error while running snippet:", e);
|
||||
showToast("Failed to run snippet :(", Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Run Snippet
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buttons.length
|
||||
? <Flex>{buttons}</Flex>
|
||||
: null;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[class*="withTagAsButton"] {
|
||||
min-width: 88px !important;
|
||||
[class*="panels"] [class*="avatarWrapper"] {
|
||||
min-width: 88px;
|
||||
}
|
||||
|
|
|
@ -222,6 +222,13 @@ export default definePlugin({
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
find: '="ActivityTrackingStore",',
|
||||
replacement: {
|
||||
match: /getVisibleRunningGames\(\).+?;(?=for)(?<=(\i)=\i\.\i\.getVisibleRunningGames.+?)/,
|
||||
replace: (m, runningGames) => `${m}${runningGames}=${runningGames}.filter(({id,name})=>$self.isActivityNotIgnored({type:0,application_id:id,name}));`
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".Messages.SETTINGS_GAMES_TOGGLE_OVERLAY",
|
||||
replacement: {
|
||||
|
|
|
@ -169,7 +169,18 @@ export function subscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof Flux
|
|||
|
||||
logger.debug("Subscribing to flux events of plugin", p.name);
|
||||
for (const [event, handler] of Object.entries(p.flux)) {
|
||||
fluxDispatcher.subscribe(event as FluxEvents, handler);
|
||||
const wrappedHandler = p.flux[event] = function () {
|
||||
try {
|
||||
const res = handler.apply(p, arguments as any);
|
||||
return res instanceof Promise
|
||||
? res.catch(e => logger.error(`${p.name}: Error while handling ${event}\n`, e))
|
||||
: res;
|
||||
} catch (e) {
|
||||
logger.error(`${p.name}: Error while handling ${event}\n`, e);
|
||||
}
|
||||
};
|
||||
|
||||
fluxDispatcher.subscribe(event as FluxEvents, wrappedHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
|||
import { ChannelStore, GuildStore } from "@webpack/common";
|
||||
|
||||
const SummaryStore = findByPropsLazy("allSummaries", "findSummary");
|
||||
const createSummaryFromServer = findByCodeLazy(".people)),startId:");
|
||||
const createSummaryFromServer = findByCodeLazy(".people)),startId:", ".type}");
|
||||
|
||||
const settings = definePluginSettings({
|
||||
summaryExpiryThresholdDays: {
|
||||
|
|
|
@ -48,10 +48,10 @@ export default definePlugin({
|
|||
},
|
||||
patches: [
|
||||
{
|
||||
find: "showTaglessAccountPanel:",
|
||||
find: '"AccountConnected"',
|
||||
replacement: {
|
||||
// react.jsx)(AccountPanel, { ..., showTaglessAccountPanel: blah })
|
||||
match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?showTaglessAccountPanel:)/,
|
||||
match: /(?<=\i\.jsxs?\)\()(\i),{(?=[^}]*?userTag:\i,hidePrivateData:)/,
|
||||
// react.jsx(WrapperComponent, { VencordOriginal: AccountPanel, ...
|
||||
replace: "$self.PanelWrapper,{VencordOriginal:$1,"
|
||||
}
|
||||
|
|
|
@ -154,104 +154,99 @@ export default definePlugin({
|
|||
}
|
||||
},
|
||||
MESSAGE_CREATE({ message, optimistic }: { message: Message; optimistic: boolean; }) {
|
||||
// Apparently without this try/catch, discord's socket connection dies if any part of this errors
|
||||
try {
|
||||
if (optimistic) return;
|
||||
const channel = ChannelStore.getChannel(message.channel_id);
|
||||
if (!shouldNotify(message, message.channel_id)) return;
|
||||
if (optimistic) return;
|
||||
const channel = ChannelStore.getChannel(message.channel_id);
|
||||
if (!shouldNotify(message, message.channel_id)) return;
|
||||
|
||||
const pingColor = settings.store.pingColor.replaceAll("#", "").trim();
|
||||
const channelPingColor = settings.store.channelPingColor.replaceAll("#", "").trim();
|
||||
let finalMsg = message.content;
|
||||
let titleString = "";
|
||||
const pingColor = settings.store.pingColor.replaceAll("#", "").trim();
|
||||
const channelPingColor = settings.store.channelPingColor.replaceAll("#", "").trim();
|
||||
let finalMsg = message.content;
|
||||
let titleString = "";
|
||||
|
||||
if (channel.guild_id) {
|
||||
const guild = GuildStore.getGuild(channel.guild_id);
|
||||
titleString = `${message.author.username} (${guild.name}, #${channel.name})`;
|
||||
}
|
||||
|
||||
|
||||
switch (channel.type) {
|
||||
case ChannelTypes.DM:
|
||||
titleString = message.author.username.trim();
|
||||
break;
|
||||
case ChannelTypes.GROUP_DM:
|
||||
const channelName = channel.name.trim() ?? channel.rawRecipients.map(e => e.username).join(", ");
|
||||
titleString = `${message.author.username} (${channelName})`;
|
||||
break;
|
||||
}
|
||||
|
||||
if (message.referenced_message) {
|
||||
titleString += " (reply)";
|
||||
}
|
||||
|
||||
if (message.embeds.length > 0) {
|
||||
finalMsg += " [embed] ";
|
||||
if (message.content === "") {
|
||||
finalMsg = "sent message embed(s)";
|
||||
}
|
||||
}
|
||||
|
||||
if (message.sticker_items) {
|
||||
finalMsg += " [sticker] ";
|
||||
if (message.content === "") {
|
||||
finalMsg = "sent a sticker";
|
||||
}
|
||||
}
|
||||
|
||||
const images = message.attachments.filter(e =>
|
||||
typeof e?.content_type === "string"
|
||||
&& e?.content_type.startsWith("image")
|
||||
);
|
||||
|
||||
|
||||
images.forEach(img => {
|
||||
finalMsg += ` [image: ${img.filename}] `;
|
||||
});
|
||||
|
||||
message.attachments.filter(a => a && !a.content_type?.startsWith("image")).forEach(a => {
|
||||
finalMsg += ` [attachment: ${a.filename}] `;
|
||||
});
|
||||
|
||||
// make mentions readable
|
||||
if (message.mentions.length > 0) {
|
||||
finalMsg = finalMsg.replace(/<@!?(\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || "unknown-user"}</color></b>`);
|
||||
}
|
||||
|
||||
// color role mentions (unity styling btw lol)
|
||||
if (message.mention_roles.length > 0) {
|
||||
for (const roleId of message.mention_roles) {
|
||||
const role = GuildStore.getRole(channel.guild_id, roleId);
|
||||
if (!role) continue;
|
||||
const roleColor = role.colorString ?? `#${pingColor}`;
|
||||
finalMsg = finalMsg.replace(`<@&${roleId}>`, `<b><color=${roleColor}>@${role.name}</color></b>`);
|
||||
}
|
||||
}
|
||||
|
||||
// make emotes and channel mentions readable
|
||||
const emoteMatches = finalMsg.match(new RegExp("(<a?:\\w+:\\d+>)", "g"));
|
||||
const channelMatches = finalMsg.match(new RegExp("<(#\\d+)>", "g"));
|
||||
|
||||
if (emoteMatches) {
|
||||
for (const eMatch of emoteMatches) {
|
||||
finalMsg = finalMsg.replace(new RegExp(`${eMatch}`, "g"), `:${eMatch.split(":")[1]}:`);
|
||||
}
|
||||
}
|
||||
|
||||
// color channel mentions
|
||||
if (channelMatches) {
|
||||
for (const cMatch of channelMatches) {
|
||||
let channelId = cMatch.split("<#")[1];
|
||||
channelId = channelId.substring(0, channelId.length - 1);
|
||||
finalMsg = finalMsg.replace(new RegExp(`${cMatch}`, "g"), `<b><color=#${channelPingColor}>#${ChannelStore.getChannel(channelId).name}</color></b>`);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldIgnoreForChannelType(channel)) return;
|
||||
sendMsgNotif(titleString, finalMsg, message);
|
||||
} catch (err) {
|
||||
XSLog.error(`Failed to catch MESSAGE_CREATE: ${err}`);
|
||||
if (channel.guild_id) {
|
||||
const guild = GuildStore.getGuild(channel.guild_id);
|
||||
titleString = `${message.author.username} (${guild.name}, #${channel.name})`;
|
||||
}
|
||||
|
||||
|
||||
switch (channel.type) {
|
||||
case ChannelTypes.DM:
|
||||
titleString = message.author.username.trim();
|
||||
break;
|
||||
case ChannelTypes.GROUP_DM:
|
||||
const channelName = channel.name.trim() ?? channel.rawRecipients.map(e => e.username).join(", ");
|
||||
titleString = `${message.author.username} (${channelName})`;
|
||||
break;
|
||||
}
|
||||
|
||||
if (message.referenced_message) {
|
||||
titleString += " (reply)";
|
||||
}
|
||||
|
||||
if (message.embeds.length > 0) {
|
||||
finalMsg += " [embed] ";
|
||||
if (message.content === "") {
|
||||
finalMsg = "sent message embed(s)";
|
||||
}
|
||||
}
|
||||
|
||||
if (message.sticker_items) {
|
||||
finalMsg += " [sticker] ";
|
||||
if (message.content === "") {
|
||||
finalMsg = "sent a sticker";
|
||||
}
|
||||
}
|
||||
|
||||
const images = message.attachments.filter(e =>
|
||||
typeof e?.content_type === "string"
|
||||
&& e?.content_type.startsWith("image")
|
||||
);
|
||||
|
||||
|
||||
images.forEach(img => {
|
||||
finalMsg += ` [image: ${img.filename}] `;
|
||||
});
|
||||
|
||||
message.attachments.filter(a => a && !a.content_type?.startsWith("image")).forEach(a => {
|
||||
finalMsg += ` [attachment: ${a.filename}] `;
|
||||
});
|
||||
|
||||
// make mentions readable
|
||||
if (message.mentions.length > 0) {
|
||||
finalMsg = finalMsg.replace(/<@!?(\d{17,20})>/g, (_, id) => `<color=#${pingColor}><b>@${UserStore.getUser(id)?.username || "unknown-user"}</color></b>`);
|
||||
}
|
||||
|
||||
// color role mentions (unity styling btw lol)
|
||||
if (message.mention_roles.length > 0) {
|
||||
for (const roleId of message.mention_roles) {
|
||||
const role = GuildStore.getRole(channel.guild_id, roleId);
|
||||
if (!role) continue;
|
||||
const roleColor = role.colorString ?? `#${pingColor}`;
|
||||
finalMsg = finalMsg.replace(`<@&${roleId}>`, `<b><color=${roleColor}>@${role.name}</color></b>`);
|
||||
}
|
||||
}
|
||||
|
||||
// make emotes and channel mentions readable
|
||||
const emoteMatches = finalMsg.match(new RegExp("(<a?:\\w+:\\d+>)", "g"));
|
||||
const channelMatches = finalMsg.match(new RegExp("<(#\\d+)>", "g"));
|
||||
|
||||
if (emoteMatches) {
|
||||
for (const eMatch of emoteMatches) {
|
||||
finalMsg = finalMsg.replace(new RegExp(`${eMatch}`, "g"), `:${eMatch.split(":")[1]}:`);
|
||||
}
|
||||
}
|
||||
|
||||
// color channel mentions
|
||||
if (channelMatches) {
|
||||
for (const cMatch of channelMatches) {
|
||||
let channelId = cMatch.split("<#")[1];
|
||||
channelId = channelId.substring(0, channelId.length - 1);
|
||||
finalMsg = finalMsg.replace(new RegExp(`${cMatch}`, "g"), `<b><color=#${channelPingColor}>#${ChannelStore.getChannel(channelId).name}</color></b>`);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldIgnoreForChannelType(channel)) return;
|
||||
sendMsgNotif(titleString, finalMsg, message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -99,3 +99,14 @@ export const isPluginDev = (id: string) => Object.hasOwn(DevsById, id);
|
|||
export function pluralise(amount: number, singular: string, plural = singular + "s") {
|
||||
return amount === 1 ? `${amount} ${singular}` : `${amount} ${plural}`;
|
||||
}
|
||||
|
||||
export function tryOrElse<T>(func: () => T, fallback: T): T {
|
||||
try {
|
||||
const res = func();
|
||||
return res instanceof Promise
|
||||
? res.catch(() => fallback) as T
|
||||
: res;
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
|
@ -131,3 +131,18 @@ export function makeCodeblock(text: string, language?: string) {
|
|||
const chars = "```";
|
||||
return `${chars}${language || ""}\n${text.replaceAll("```", "\\`\\`\\`")}\n${chars}`;
|
||||
}
|
||||
|
||||
export function stripIndent(strings: TemplateStringsArray, ...values: any[]) {
|
||||
const string = String.raw({ raw: strings }, ...values);
|
||||
|
||||
const match = string.match(/^[ \t]*(?=\S)/gm);
|
||||
if (!match) return string.trim();
|
||||
|
||||
const minIndent = match.reduce((r, a) => Math.min(r, a.length), Infinity);
|
||||
return string.replace(new RegExp(`^[ \\t]{${minIndent}}`, "gm"), "").trim();
|
||||
}
|
||||
|
||||
export const ZWSP = "\u200b";
|
||||
export function toInlineCode(s: string) {
|
||||
return "``" + ZWSP + s.replaceAll("`", ZWSP + "`" + ZWSP) + ZWSP + "``";
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ export interface PluginDef {
|
|||
* Allows you to subscribe to Flux events
|
||||
*/
|
||||
flux?: {
|
||||
[E in FluxEvents]?: (event: any) => void;
|
||||
[E in FluxEvents]?: (event: any) => void | Promise<void>;
|
||||
};
|
||||
/**
|
||||
* Allows you to manipulate context menus
|
||||
|
|
|
@ -8,7 +8,12 @@ export let EXTENSION_BASE_URL: string;
|
|||
export let EXTENSION_VERSION: string;
|
||||
|
||||
if (IS_EXTENSION) {
|
||||
const script = document.querySelector("#vencord-script") as HTMLScriptElement;
|
||||
EXTENSION_BASE_URL = script.dataset.extensionBaseUrl!;
|
||||
EXTENSION_VERSION = script.dataset.version!;
|
||||
const listener = (e: MessageEvent) => {
|
||||
if (e.data?.type === "vencord:meta") {
|
||||
({ EXTENSION_BASE_URL, EXTENSION_VERSION } = e.data.meta);
|
||||
window.removeEventListener("message", listener);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("message", listener);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue