{sortedPlugins?.length ? sortedPlugins
.filter(a => !a.required && !dependencyCheck(a.name, depMap).length && pluginFilter(a))
diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx
deleted file mode 100644
index f8e74955f..000000000
--- a/src/components/Settings.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Vencord, a modification for Discord's desktop app
- * Copyright (c) 2022 Vendicated and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
-*/
-
-import { useSettings } from "../api/settings";
-import IpcEvents from "../utils/IpcEvents";
-import { useAwaiter } from "../utils/misc";
-import { downloadSettingsBackup, uploadSettingsBackup } from "../utils/settingsSync";
-import { Button, Card, Forms, Margins, React, Switch } from "../webpack/common";
-import DonateButton from "./DonateButton";
-import ErrorBoundary from "./ErrorBoundary";
-import { Flex } from "./Flex";
-import { handleComponentFailed } from "./handleComponentFailed";
-
-export default ErrorBoundary.wrap(function Settings() {
- const [settingsDir, , settingsDirPending] = useAwaiter(() => VencordNative.ipc.invoke(IpcEvents.GET_SETTINGS_DIR), "Loading...");
- const settings = useSettings();
-
- return (
-
-
-
- Support the Project
-
- Please consider supporting the Development of Vencord by donating!
-
-
-
-
-
-
-
- Settings
-
-
-
- Settings Directory: {settingsDir}
-
-
- {!IS_WEB &&
-
-
-
- }
-
- {IS_WEB && }
-
-
- settings.useQuickCss = v}
- note="Loads styles from your QuickCss file"
- >
- Use QuickCss
-
- {!IS_WEB && settings.enableReactDevtools = v}
- note="Requires a full restart"
- >
- Enable React Developer Tools
- }
- {!IS_WEB && settings.notifyAboutUpdates = v}
- note="Shows a Toast on StartUp"
- >
- Get notified about new Updates
- }
-
-
- Settings Sync
-
-
-
-
-
- );
-}, {
- message: "Failed to render the Settings. If this persists, try using the installer to reinstall!",
- onError: handleComponentFailed,
-});
diff --git a/src/components/VencordSettings/BackupRestoreTab.tsx b/src/components/VencordSettings/BackupRestoreTab.tsx
new file mode 100644
index 000000000..ce0bdaa6e
--- /dev/null
+++ b/src/components/VencordSettings/BackupRestoreTab.tsx
@@ -0,0 +1,69 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+import { downloadSettingsBackup, uploadSettingsBackup } from "../../utils/settingsSync";
+import { Button, Card, Forms, Margins, Text } from "../../webpack/common";
+import ErrorBoundary from "../ErrorBoundary";
+import { Flex } from "../Flex";
+
+function BackupRestoreTab() {
+ return (
+
+
+
+ Warning
+ Importing a settings file will overwrite your current settings.
+
+
+
+ You can import and export your Vencord settings as a JSON file.
+ This allows you to easily transfer your settings to another device,
+ or recover your settings after reinstalling Vencord or Discord.
+
+
+ Settings Export contains:
+
+
— Custom QuickCSS
+
— Plugin Settings
+
+
+
+
+
+
+
+ );
+}
+
+export default ErrorBoundary.wrap(BackupRestoreTab);
diff --git a/src/components/VencordSettings/PluginsTab.tsx b/src/components/VencordSettings/PluginsTab.tsx
new file mode 100644
index 000000000..0c8968637
--- /dev/null
+++ b/src/components/VencordSettings/PluginsTab.tsx
@@ -0,0 +1,22 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+import ErrorBoundary from "../ErrorBoundary";
+import PluginSettings from "../PluginSettings";
+
+export default ErrorBoundary.wrap(PluginSettings);
diff --git a/src/components/Updater.tsx b/src/components/VencordSettings/Updater.tsx
similarity index 94%
rename from src/components/Updater.tsx
rename to src/components/VencordSettings/Updater.tsx
index 8abdf288f..8f2b75beb 100644
--- a/src/components/Updater.tsx
+++ b/src/components/VencordSettings/Updater.tsx
@@ -18,14 +18,14 @@
import gitHash from "~git-hash";
-import { classes, useAwaiter } from "../utils/misc";
-import { changes, checkForUpdates, getRepo, isNewer, rebuild, update, updateError, UpdateLogger } from "../utils/updater";
-import { Alerts, Button, Card, Forms, Margins, Parser, React, Toasts } from "../webpack/common";
-import ErrorBoundary from "./ErrorBoundary";
-import { ErrorCard } from "./ErrorCard";
-import { Flex } from "./Flex";
-import { handleComponentFailed } from "./handleComponentFailed";
-import { Link } from "./Link";
+import { classes, useAwaiter } from "../../utils/misc";
+import { changes, checkForUpdates, getRepo, isNewer, rebuild, update, updateError, UpdateLogger } from "../../utils/updater";
+import { Alerts, Button, Card, Forms, Margins, Parser, React, Toasts } from "../../webpack/common";
+import ErrorBoundary from "../ErrorBoundary";
+import { ErrorCard } from "../ErrorCard";
+import { Flex } from "../Flex";
+import { handleComponentFailed } from "../handleComponentFailed";
+import { Link } from "../Link";
function withDispatcher(dispatcher: React.Dispatch>, action: () => any) {
return async () => {
@@ -192,7 +192,7 @@ function Updater() {
};
return (
-
+ Repo{repoPending ? repo : err ? "Failed to retrieve - check console" : (
diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx
new file mode 100644
index 000000000..94add5ed6
--- /dev/null
+++ b/src/components/VencordSettings/VencordTab.tsx
@@ -0,0 +1,134 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+
+import { useSettings } from "../../api/settings";
+import IpcEvents from "../../utils/IpcEvents";
+import { useAwaiter } from "../../utils/misc";
+import { Button, Card, Forms, React, Switch } from "../../webpack/common";
+import DonateButton from "../DonateButton";
+import ErrorBoundary from "../ErrorBoundary";
+
+const st = (style: string) => `vcSettings${style}`;
+
+function VencordSettings() {
+ const [settingsDir, , settingsDirPending] = useAwaiter(() => VencordNative.ipc.invoke(IpcEvents.GET_SETTINGS_DIR), "Loading...");
+ const settings = useSettings();
+
+ return (
+
+
+
+
+ {IS_WEB ? (
+
+ ) : (
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+ settings.useQuickCss = v}
+ note="Loads styles from your QuickCss file">
+ Use QuickCss
+
+ {!IS_WEB && (
+
+ settings.enableReactDevtools = v}
+ note="Requires a full restart">
+ Enable React Developer Tools
+
+ settings.notifyAboutUpdates = v}
+ note="Shows a Toast on StartUp">
+ Get notified about new Updates
+
+
+ )}
+
+
+
+ );
+}
+
+
+
+function DonateCard() {
+ return (
+
+
+ Support the Project
+
+ Please consider supporting the Development of Vencord by donating!
+
+
+
+
+
+ );
+}
+
+export default ErrorBoundary.wrap(VencordSettings);
diff --git a/src/components/VencordSettings/index.tsx b/src/components/VencordSettings/index.tsx
new file mode 100644
index 000000000..370189786
--- /dev/null
+++ b/src/components/VencordSettings/index.tsx
@@ -0,0 +1,84 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+import cssText from "~fileContent/settingsStyles.css";
+
+import { lazyWebpack } from "../../utils/misc";
+import { filters } from "../../webpack";
+import { Forms, React, Router, Text } from "../../webpack/common";
+import ErrorBoundary from "../ErrorBoundary";
+import BackupRestoreTab from "./BackupRestoreTab";
+import PluginsTab from "./PluginsTab";
+import Updater from "./Updater";
+import VencordSettings from "./VencordTab";
+
+const style = document.createElement("style");
+style.textContent = cssText;
+document.head.appendChild(style);
+
+const st = (style: string) => `vcSettings${style}`;
+
+const TabBar = lazyWebpack(filters.byCode('[role="tab"][aria-disabled="false"]'));
+
+interface SettingsProps {
+ tab: string;
+}
+
+const SettingsTabs = {
+ VencordSettings: { name: "Vencord", component: () => },
+ VencordPlugins: { name: "Plugins", component: () => },
+ VencordThemes: { name: "Themes", component: () => Coming soon to a Vencord near you! },
+ VencordUpdater: { name: "Updater", component: () => Updater ? : null },
+ VencordSettingsSync: { name: "Backup & Restore", component: () => },
+};
+
+
+function Settings(props: SettingsProps) {
+ const { tab = "VencordSettings" } = props;
+
+ const CurrentTab = SettingsTabs[tab]?.component ?? null;
+
+ return
+ Vencord Settings
+
+
+ {Object.entries(SettingsTabs).map(([key, { name }]) => {
+ return
+ {name}
+ ;
+ })}
+
+
+
+ ;
+}
+
+export default function (props: SettingsProps) {
+ return
+
+ ;
+}
diff --git a/src/components/VencordSettings/settingsStyles.css b/src/components/VencordSettings/settingsStyles.css
new file mode 100644
index 000000000..e90ef141b
--- /dev/null
+++ b/src/components/VencordSettings/settingsStyles.css
@@ -0,0 +1,23 @@
+.vcSettingsTabBar {
+ margin-top: 20px;
+ margin-bottom: -2px;
+ border-bottom: 2px solid var(--background-modifier-accent);
+}
+
+.vcSettingsTabBarItem {
+ margin-right: 32px;
+ padding-bottom: 16px;
+ margin-bottom: -2px;
+}
+
+.vcSettingsQuickActionCard {
+ padding: 1em;
+ display: flex;
+ gap: 1em;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ flex-grow: 1;
+ flex-direction: row;
+ margin-bottom: 1em;
+}
diff --git a/src/components/index.ts b/src/components/index.ts
index 80d2cd129..3ee53b02c 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -18,5 +18,4 @@
export { default as PatchHelper } from "./PatchHelper";
export { default as PluginSettings } from "./PluginSettings";
-export { default as Settings } from "./Settings";
-export { default as Updater } from "./Updater";
+export { default as VencordSettings } from "./VencordSettings";
diff --git a/src/plugins/settings.tsx b/src/plugins/settings.tsx
index ec4295667..27775725b 100644
--- a/src/plugins/settings.tsx
+++ b/src/plugins/settings.tsx
@@ -19,8 +19,11 @@
import gitHash from "~git-hash";
import { Devs } from "../utils/constants";
+import { LazyComponent } from "../utils/misc";
import definePlugin from "../utils/types";
+const SettingsComponent = LazyComponent(() => require("../components/VencordSettings").default);
+
export default definePlugin({
name: "Settings",
description: "Adds Settings UI and debug info",
@@ -42,13 +45,15 @@ export default definePlugin({
replacement: {
match: /\{section:(.{1,2})\.ID\.HEADER,\s*label:(.{1,2})\..{1,2}\.Messages\.ACTIVITY_SETTINGS\}/,
replace: (m, mod) => {
- const updater = !IS_WEB ? '{section:"VencordUpdater",label:"Updater",element:Vencord.Components.Updater},' : "";
- const patchHelper = IS_DEV ? '{section:"VencordPatchHelper",label:"PatchHelper",element:Vencord.Components.PatchHelper},' : "";
+ const updater = !IS_WEB ? '{section:"VencordUpdater",label:"Updater",element:Vencord.Plugins.plugins.Settings.tabs.updater},' : "";
+ const patchHelper = IS_DEV ? '{section:"VencordPatchHelper",label:"Patch Helper",element:Vencord.Components.PatchHelper},' : "";
return (
`{section:${mod}.ID.HEADER,label:"Vencord"},` +
- '{section:"VencordSetting",label:"Vencord",element:Vencord.Components.Settings},' +
- '{section:"VencordPlugins",label:"Plugins",element:Vencord.Components.PluginSettings},' +
+ '{section:"VencordSettings",label:"Vencord",element:Vencord.Plugins.plugins.Settings.tabs.vencord},' +
+ '{section:"VencordPlugins",label:"Plugins",element:Vencord.Plugins.plugins.Settings.tabs.plugins},' +
+ '{section:"VencordThemes",label:"Themes",element:Vencord.Plugins.plugins.Settings.tabs.themes},' +
updater +
+ '{section:"VencordSettingsSync",label:"Backup & Restore",element:Vencord.Plugins.plugins.Settings.tabs.sync},' +
patchHelper +
`{section:${mod}.ID.DIVIDER},${m}`
);
@@ -56,6 +61,14 @@ export default definePlugin({
}
}],
+ tabs: {
+ vencord: () => ,
+ plugins: () => ,
+ themes: () => ,
+ updater: () => ,
+ sync: () =>
+ },
+
get electronVersion() {
return VencordNative.getVersions().electron || window.armcord?.electron || null;
},
diff --git a/src/plugins/spotifyControls/SpotifyStore.ts b/src/plugins/spotifyControls/SpotifyStore.ts
index 0dad5038b..14f233182 100644
--- a/src/plugins/spotifyControls/SpotifyStore.ts
+++ b/src/plugins/spotifyControls/SpotifyStore.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import cssText from "~fileContent/styles.css";
+import cssText from "~fileContent/spotifyStyles.css";
import IpcEvents from "../../utils/IpcEvents";
import { lazyWebpack } from "../../utils/misc";
diff --git a/src/plugins/spotifyControls/styles.css b/src/plugins/spotifyControls/spotifyStyles.css
similarity index 100%
rename from src/plugins/spotifyControls/styles.css
rename to src/plugins/spotifyControls/spotifyStyles.css
diff --git a/src/webpack/common.tsx b/src/webpack/common.tsx
index 2f3768eb9..32f47e663 100644
--- a/src/webpack/common.tsx
+++ b/src/webpack/common.tsx
@@ -195,7 +195,7 @@ export type TextProps = React.PropsWithChildren & {
className?: string;
};
-export type TextVariant = "heading-sm/normal" | "heading-sm/medium" | "heading-sm/bold" | "heading-md/normal" | "heading-md/medium" | "heading-md/bold" | "heading-lg/normal" | "heading-lg/medium" | "heading-lg/bold" | "heading-xl/normal" | "heading-xl/medium" | "heading-xl/bold" | "heading-xxl/normal" | "heading-xxl/medium" | "heading-xxl/bold" | "eyebrow" | "heading-deprecated-14/normal" | "heading-deprecated-14/medium" | "heading-deprecated-14/bold" | "text-xxs/normal" | "text-xxs/medium" | "text-xxs/semibold" | "text-xxs/bold" | "text-xs/normal" | "text-xs/medium" | "text-xs/semibold" | "text-xs/bold" | "text-sm/normal" | "text-sm/medium" | "text-sm/semibold" | "text-sm/bold" | "text-md/normal" | "text-md/medium" | "text-md/semibold" | "text-md/bold" | "text-lg/normal" | "text-lg/medium" | "text-lg/semibold" | "text-lg/bold" | "display-md" | "display-lg" | "code";
+export type TextVariant = "heading-sm/normal" | "heading-sm/medium" | "heading-sm/bold" | "heading-md/normal" | "heading-md/medium" | "heading-md/bold" | "heading-lg/normal" | "heading-lg/medium" | "heading-lg/bold" | "heading-xl/normal" | "heading-xl/medium" | "heading-xl/bold" | "heading-xxl/normal" | "heading-xxl/medium" | "heading-xxl/bold" | "eyebrow" | "heading-deprecated-14/normal" | "heading-deprecated-14/medium" | "heading-deprecated-14/bold" | "text-xxs/normal" | "text-xxs/medium" | "text-xxs/semibold" | "text-xxs/bold" | "text-xs/normal" | "text-xs/medium" | "text-xs/semibold" | "text-xs/bold" | "text-sm/normal" | "text-sm/medium" | "text-sm/semibold" | "text-sm/bold" | "text-md/normal" | "text-md/medium" | "text-md/semibold" | "text-md/bold" | "text-lg/normal" | "text-lg/medium" | "text-lg/semibold" | "text-lg/bold" | "display-sm" | "display-md" | "display-lg" | "code";
type RC = React.ComponentType>>;
interface Menu {