From 6b55dee9fbba1a54cbe2ba1f2067e2d14190ab93 Mon Sep 17 00:00:00 2001 From: megumin Date: Fri, 25 Nov 2022 22:38:55 +0000 Subject: feat(settings): new settings design (#261) --- src/components/PatchHelper.tsx | 7 +- src/components/PluginSettings/index.tsx | 6 +- src/components/Settings.tsx | 140 ------------- src/components/Updater.tsx | 216 --------------------- .../VencordSettings/BackupRestoreTab.tsx | 69 +++++++ src/components/VencordSettings/PluginsTab.tsx | 22 +++ src/components/VencordSettings/Updater.tsx | 216 +++++++++++++++++++++ src/components/VencordSettings/VencordTab.tsx | 134 +++++++++++++ src/components/VencordSettings/index.tsx | 84 ++++++++ src/components/VencordSettings/settingsStyles.css | 23 +++ src/components/index.ts | 3 +- src/plugins/settings.tsx | 21 +- src/plugins/spotifyControls/SpotifyStore.ts | 2 +- src/plugins/spotifyControls/spotifyStyles.css | 181 +++++++++++++++++ src/plugins/spotifyControls/styles.css | 181 ----------------- src/webpack/common.tsx | 2 +- 16 files changed, 757 insertions(+), 550 deletions(-) delete mode 100644 src/components/Settings.tsx delete mode 100644 src/components/Updater.tsx create mode 100644 src/components/VencordSettings/BackupRestoreTab.tsx create mode 100644 src/components/VencordSettings/PluginsTab.tsx create mode 100644 src/components/VencordSettings/Updater.tsx create mode 100644 src/components/VencordSettings/VencordTab.tsx create mode 100644 src/components/VencordSettings/index.tsx create mode 100644 src/components/VencordSettings/settingsStyles.css create mode 100644 src/plugins/spotifyControls/spotifyStyles.css delete mode 100644 src/plugins/spotifyControls/styles.css (limited to 'src') diff --git a/src/components/PatchHelper.tsx b/src/components/PatchHelper.tsx index 82b804a..0314de8 100644 --- a/src/components/PatchHelper.tsx +++ b/src/components/PatchHelper.tsx @@ -18,7 +18,7 @@ import { debounce } from "../utils/debounce"; import { makeCodeblock } from "../utils/misc"; -import { Button, Clipboard, Forms, Margins, Parser, React, Switch, TextInput } from "../webpack/common"; +import { Button, Clipboard, Forms, Margins, Parser, React, Switch, Text, TextInput } from "../webpack/common"; import { search } from "../webpack/webpack"; import { CheckedTextInput } from "./CheckedTextInput"; import ErrorBoundary from "./ErrorBoundary"; @@ -243,7 +243,8 @@ function PatchHelper() { } return ( - <> + + Patch Helper find Clipboard.copy(code)}>Copy to Clipboard )} - + ); } diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index 39fb911..f16d55c 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -243,9 +243,9 @@ export default ErrorBoundary.wrap(function Settings() { }; return ( - + - Plugins + Filters @@ -268,6 +268,8 @@ export default ErrorBoundary.wrap(function Settings() { + Plugins +
{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 f8e7495..0000000 --- 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/Updater.tsx b/src/components/Updater.tsx deleted file mode 100644 index 8abdf28..0000000 --- a/src/components/Updater.tsx +++ /dev/null @@ -1,216 +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 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"; - -function withDispatcher(dispatcher: React.Dispatch>, action: () => any) { - return async () => { - dispatcher(true); - try { - await action(); - } catch (e: any) { - UpdateLogger.error("Failed to update", e); - if (!e) { - var err = "An unknown error occurred (error is undefined).\nPlease try again."; - } else if (e.code && e.cmd) { - const { code, path, cmd, stderr } = e; - - if (code === "ENOENT") - var err = `Command \`${path}\` not found.\nPlease install it and try again`; - else { - var err = `An error occured while running \`${cmd}\`:\n`; - err += stderr || `Code \`${code}\`. See the console for more info`; - } - - } else { - var err = "An unknown error occurred. See the console for more info."; - } - Alerts.show({ - title: "Oops!", - body: ( - - {err.split("\n").map(line =>
{Parser.parse(line)}
)} -
- ) - }); - } - finally { - dispatcher(false); - } - }; -} - -interface CommonProps { - repo: string; - repoPending: boolean; -} - -function Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof changes; }) { - return ( - - {updates.map(({ hash, author, message }) => ( -
- - {hash} - - {message} - {author} -
- ))} -
- ); -} - -function Updatable(props: CommonProps) { - const [updates, setUpdates] = React.useState(changes); - const [isChecking, setIsChecking] = React.useState(false); - const [isUpdating, setIsUpdating] = React.useState(false); - - const isOutdated = (updates?.length ?? 0) > 0; - - return ( - <> - {!updates && updateError ? ( - <> - Failed to check updates. Check the console for more info - -

{updateError.stderr || updateError.stdout || "An unknown error occurred"}

-
- - ) : ( - - {isOutdated ? `There are ${updates.length} Updates` : "Up to Date!"} - - )} - - {isOutdated && } - - - {isOutdated && } - - - - ); -} - -function Newer(props: CommonProps) { - return ( - <> - - Your local copy has more recent commits. Please stash or reset them. - - - - ); -} - -function Updater() { - const [repo, err, repoPending] = useAwaiter(getRepo, "Loading..."); - - React.useEffect(() => { - if (err) - UpdateLogger.error("Failed to retrieve repo", err); - }, [err]); - - const commonProps: CommonProps = { - repo, - repoPending - }; - - return ( - - Repo - - {repoPending ? repo : err ? "Failed to retrieve - check console" : ( - - {repo.split("/").slice(-2).join("/")} - - )} ({gitHash}) - - - - Updates - - {isNewer ? : } - - ); -} - -export default IS_WEB ? null : ErrorBoundary.wrap(Updater, { - message: "Failed to render the Updater. 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 0000000..ce0bdaa --- /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 0000000..0c89686 --- /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/VencordSettings/Updater.tsx b/src/components/VencordSettings/Updater.tsx new file mode 100644 index 0000000..8f2b75b --- /dev/null +++ b/src/components/VencordSettings/Updater.tsx @@ -0,0 +1,216 @@ +/* + * 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 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"; + +function withDispatcher(dispatcher: React.Dispatch>, action: () => any) { + return async () => { + dispatcher(true); + try { + await action(); + } catch (e: any) { + UpdateLogger.error("Failed to update", e); + if (!e) { + var err = "An unknown error occurred (error is undefined).\nPlease try again."; + } else if (e.code && e.cmd) { + const { code, path, cmd, stderr } = e; + + if (code === "ENOENT") + var err = `Command \`${path}\` not found.\nPlease install it and try again`; + else { + var err = `An error occured while running \`${cmd}\`:\n`; + err += stderr || `Code \`${code}\`. See the console for more info`; + } + + } else { + var err = "An unknown error occurred. See the console for more info."; + } + Alerts.show({ + title: "Oops!", + body: ( + + {err.split("\n").map(line =>
{Parser.parse(line)}
)} +
+ ) + }); + } + finally { + dispatcher(false); + } + }; +} + +interface CommonProps { + repo: string; + repoPending: boolean; +} + +function Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof changes; }) { + return ( + + {updates.map(({ hash, author, message }) => ( +
+ + {hash} + + {message} - {author} +
+ ))} +
+ ); +} + +function Updatable(props: CommonProps) { + const [updates, setUpdates] = React.useState(changes); + const [isChecking, setIsChecking] = React.useState(false); + const [isUpdating, setIsUpdating] = React.useState(false); + + const isOutdated = (updates?.length ?? 0) > 0; + + return ( + <> + {!updates && updateError ? ( + <> + Failed to check updates. Check the console for more info + +

{updateError.stderr || updateError.stdout || "An unknown error occurred"}

+
+ + ) : ( + + {isOutdated ? `There are ${updates.length} Updates` : "Up to Date!"} + + )} + + {isOutdated && } + + + {isOutdated && } + + + + ); +} + +function Newer(props: CommonProps) { + return ( + <> + + Your local copy has more recent commits. Please stash or reset them. + + + + ); +} + +function Updater() { + const [repo, err, repoPending] = useAwaiter(getRepo, "Loading..."); + + React.useEffect(() => { + if (err) + UpdateLogger.error("Failed to retrieve repo", err); + }, [err]); + + const commonProps: CommonProps = { + repo, + repoPending + }; + + return ( + + Repo + + {repoPending ? repo : err ? "Failed to retrieve - check console" : ( + + {repo.split("/").slice(-2).join("/")} + + )} ({gitHash}) + + + + Updates + + {isNewer ? : } + + ); +} + +export default IS_WEB ? null : ErrorBoundary.wrap(Updater, { + message: "Failed to render the Updater. If this persists, try using the installer to reinstall!", + onError: handleComponentFailed, +}); diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx new file mode 100644 index 0000000..94add5e --- /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 0000000..3701897 --- /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 0000000..e90ef14 --- /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 80d2cd1..3ee53b0 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 ec42956..2777572 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 0dad503..14f2331 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/spotifyStyles.css b/src/plugins/spotifyControls/spotifyStyles.css new file mode 100644 index 0000000..9c7b1c0 --- /dev/null +++ b/src/plugins/spotifyControls/spotifyStyles.css @@ -0,0 +1,181 @@ +#vc-spotify-player { + padding: 0.375rem 0.5rem; + border-bottom: 1px solid var(--background-modifier-accent); + --vc-spotify-green: #1db954; /* so cusotm themes can easily change it */ +} +.vc-spotify-button { + background: none; + color: var(--interactive-normal); + padding: 0; + width: 32px; + height: 32px; + + border-radius: 100%; + display: flex; + justify-content: center; + align-items: center; +} +.vc-spotify-button:hover { + color: var(--interactive-hover); + background-color: var(--background-modifier-selected); +} + +.vc-spotify-button svg { + height: 24px; + width: 24px; +} +[class*="vc-spotify-shuffle"] > svg, +[class*="vc-spotify-repeat"] > svg { + width: 22px; + height: 22px; +} +.vc-spotify-button svg path { + width: 100%; + height: 100%; +} +/* .vc-spotify-button:hover { + filter: brightness(1.3); +} */ + +.vc-spotify-shuffle-on, +.vc-spotify-repeat-context, +.vc-spotify-repeat-track, +.vc-spotify-shuffle-on:hover, +.vc-spotify-repeat-context:hover, +.vc-spotify-repeat-track:hover { + color: var(--vc-spotify-green); +} + +.vc-spotify-tooltip-text { + overflow: hidden; + white-space: nowrap; + padding-right: 0.2em; + max-width: 100%; +} +.vc-spotify-repeat-1 { + font-size: 70%; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.vc-spotify-button-row { + justify-content: center; +} + +#vc-spotify-info-wrapper { + display: flex; + flex-direction: row; + align-items: center; + height: 3em; + gap: 0.5em; +} + +#vc-spotify-info-wrapper img { + height: 90%; + object-fit: contain; +} + +#vc-spotify-album-expanded-wrapper img { + width: 100%; + object-fit: contain; +} + +#vc-spotify-titles { + display: flex; + flex-direction: column; + padding: 0.2rem; + justify-content: center; + align-items: flex-start; + align-content: flex-start; + overflow: hidden; +} + +.vc-spotify-tooltip-text { + margin: unset; +} + +#vc-spotify-song-title { + color: var(--header-primary); + font-size: 14px; + font-weight: 600; +} +.vc-spotify-ellipoverflow { + white-space: nowrap; + overflow: hidden; + width: 100%; + text-overflow: ellipsis; +} + +.vc-spotify-artist, +.vc-spotify-album { + font-size: 12px; + text-decoration: none; + color: var(--header-secondary); +} + +.vc-spotify-comma { + color: var(--header-secondary); +} + +.vc-spotify-artist:hover, +#vc-spotify-album-title:hover, +#vc-spotify-song-title[role="link"]:hover { + text-decoration: underline; + cursor: pointer; +} + +#vc-spotify-album-image { + border-radius: 3px; +} + +#vc-spotify-album-image:hover { + filter: brightness(1.2); + cursor: pointer; +} + +#vc-spotify-progress-bar { + position: relative; + + color: var(--text-normal); + width: 100%; + margin: 0.5em 0; + margin-bottom: 5px; +} + +#vc-spotify-progress-bar > [class^="slider"] { + flex-grow: 1; + width: 100%; + padding: 0 !important; +} + +#vc-spotify-progress-bar > [class^="slider"] [class^="bar-"] { + height: 4px !important; +} +#vc-spotify-progress-bar > [class^="slider"] [class^="grabber"] { + /* these importants are neccessary, it applies a width and height through inline styles */ + height: 10px !important; + width: 10px !important; + background-color: var(--interactive-normal); + border-color: var(--interactive-normal); + color: var(--interactive-normal); +} + +#vc-spotify-progress-text { + margin: 0; +} + +.vc-spotify-progress-time { + font-size: 12px; + + top: 10px; + position: absolute; +} + +.vc-spotify-time-left { + left: 0; +} +.vc-spotify-time-right { + right: 0; +} diff --git a/src/plugins/spotifyControls/styles.css b/src/plugins/spotifyControls/styles.css deleted file mode 100644 index 9c7b1c0..0000000 --- a/src/plugins/spotifyControls/styles.css +++ /dev/null @@ -1,181 +0,0 @@ -#vc-spotify-player { - padding: 0.375rem 0.5rem; - border-bottom: 1px solid var(--background-modifier-accent); - --vc-spotify-green: #1db954; /* so cusotm themes can easily change it */ -} -.vc-spotify-button { - background: none; - color: var(--interactive-normal); - padding: 0; - width: 32px; - height: 32px; - - border-radius: 100%; - display: flex; - justify-content: center; - align-items: center; -} -.vc-spotify-button:hover { - color: var(--interactive-hover); - background-color: var(--background-modifier-selected); -} - -.vc-spotify-button svg { - height: 24px; - width: 24px; -} -[class*="vc-spotify-shuffle"] > svg, -[class*="vc-spotify-repeat"] > svg { - width: 22px; - height: 22px; -} -.vc-spotify-button svg path { - width: 100%; - height: 100%; -} -/* .vc-spotify-button:hover { - filter: brightness(1.3); -} */ - -.vc-spotify-shuffle-on, -.vc-spotify-repeat-context, -.vc-spotify-repeat-track, -.vc-spotify-shuffle-on:hover, -.vc-spotify-repeat-context:hover, -.vc-spotify-repeat-track:hover { - color: var(--vc-spotify-green); -} - -.vc-spotify-tooltip-text { - overflow: hidden; - white-space: nowrap; - padding-right: 0.2em; - max-width: 100%; -} -.vc-spotify-repeat-1 { - font-size: 70%; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - -.vc-spotify-button-row { - justify-content: center; -} - -#vc-spotify-info-wrapper { - display: flex; - flex-direction: row; - align-items: center; - height: 3em; - gap: 0.5em; -} - -#vc-spotify-info-wrapper img { - height: 90%; - object-fit: contain; -} - -#vc-spotify-album-expanded-wrapper img { - width: 100%; - object-fit: contain; -} - -#vc-spotify-titles { - display: flex; - flex-direction: column; - padding: 0.2rem; - justify-content: center; - align-items: flex-start; - align-content: flex-start; - overflow: hidden; -} - -.vc-spotify-tooltip-text { - margin: unset; -} - -#vc-spotify-song-title { - color: var(--header-primary); - font-size: 14px; - font-weight: 600; -} -.vc-spotify-ellipoverflow { - white-space: nowrap; - overflow: hidden; - width: 100%; - text-overflow: ellipsis; -} - -.vc-spotify-artist, -.vc-spotify-album { - font-size: 12px; - text-decoration: none; - color: var(--header-secondary); -} - -.vc-spotify-comma { - color: var(--header-secondary); -} - -.vc-spotify-artist:hover, -#vc-spotify-album-title:hover, -#vc-spotify-song-title[role="link"]:hover { - text-decoration: underline; - cursor: pointer; -} - -#vc-spotify-album-image { - border-radius: 3px; -} - -#vc-spotify-album-image:hover { - filter: brightness(1.2); - cursor: pointer; -} - -#vc-spotify-progress-bar { - position: relative; - - color: var(--text-normal); - width: 100%; - margin: 0.5em 0; - margin-bottom: 5px; -} - -#vc-spotify-progress-bar > [class^="slider"] { - flex-grow: 1; - width: 100%; - padding: 0 !important; -} - -#vc-spotify-progress-bar > [class^="slider"] [class^="bar-"] { - height: 4px !important; -} -#vc-spotify-progress-bar > [class^="slider"] [class^="grabber"] { - /* these importants are neccessary, it applies a width and height through inline styles */ - height: 10px !important; - width: 10px !important; - background-color: var(--interactive-normal); - border-color: var(--interactive-normal); - color: var(--interactive-normal); -} - -#vc-spotify-progress-text { - margin: 0; -} - -.vc-spotify-progress-time { - font-size: 12px; - - top: 10px; - position: absolute; -} - -.vc-spotify-time-left { - left: 0; -} -.vc-spotify-time-right { - right: 0; -} diff --git a/src/webpack/common.tsx b/src/webpack/common.tsx index 2f3768e..32f47e6 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 { -- cgit