diff --git a/src/components/settings/tabs/themes/CspErrorCard.tsx b/src/components/settings/tabs/themes/CspErrorCard.tsx deleted file mode 100644 index ee885647e..000000000 --- a/src/components/settings/tabs/themes/CspErrorCard.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { ErrorCard } from "@components/ErrorCard"; -import { Link } from "@components/Link"; -import { CspBlockedUrls, useCspErrors } from "@utils/cspViolations"; -import { Margins } from "@utils/margins"; -import { classes } from "@utils/misc"; -import { relaunch } from "@utils/native"; -import { useForceUpdater } from "@utils/react"; -import { Alerts, Button, Forms } from "@webpack/common"; - -export function CspErrorCard() { - if (IS_WEB) return null; - - const errors = useCspErrors(); - const forceUpdate = useForceUpdater(); - - if (!errors.length) return null; - - const isImgurHtmlDomain = (url: string) => url.startsWith("https://imgur.com/"); - - const allowUrl = async (url: string) => { - const { origin: baseUrl, host } = new URL(url); - - const result = await VencordNative.csp.requestAddOverride(baseUrl, ["connect-src", "img-src", "style-src", "font-src"], "Vencord Themes"); - if (result !== "ok") return; - - CspBlockedUrls.forEach(url => { - if (new URL(url).host === host) { - CspBlockedUrls.delete(url); - } - }); - - forceUpdate(); - - Alerts.show({ - title: "Restart Required", - body: "A restart is required to apply this change", - confirmText: "Restart now", - cancelText: "Later!", - onConfirm: relaunch - }); - }; - - const hasImgurHtmlDomain = errors.some(isImgurHtmlDomain); - - return ( - - Blocked Resources - Some images, styles, or fonts were blocked because they come from disallowed domains. - It is highly recommended to move them to GitHub or Imgur. But you may also allow domains if you fully trust them. - - After allowing a domain, you have to fully close (from tray / task manager) and restart {IS_DISCORD_DESKTOP ? "Discord" : "Vesktop"} to apply the change. - - - Blocked URLs - - {errors.map((url, i) => ( - - {i !== 0 && } - - {url} - allowUrl(url)} disabled={isImgurHtmlDomain(url)}> - Allow - - - - ))} - - - {hasImgurHtmlDomain && ( - <> - - - Imgur links should be direct links in the form of https://i.imgur.com/... - - To obtain a direct link, right-click the image and select "Copy image address". - > - )} - - ); -} diff --git a/src/components/settings/tabs/themes/LocalThemesTab.tsx b/src/components/settings/tabs/themes/LocalThemesTab.tsx deleted file mode 100644 index 8d07a27cd..000000000 --- a/src/components/settings/tabs/themes/LocalThemesTab.tsx +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Settings, useSettings } from "@api/Settings"; -import { classNameFactory } from "@api/Styles"; -import { FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons"; -import { Link } from "@components/Link"; -import { QuickAction, QuickActionCard } from "@components/settings/QuickAction"; -import { openPluginModal } from "@components/settings/tabs/plugins/PluginModal"; -import { UserThemeHeader } from "@main/themes"; -import { findLazy } from "@webpack"; -import { Card, Forms, useEffect, useRef, useState } from "@webpack/common"; -import ClientThemePlugin from "plugins/clientTheme"; -import type { ComponentType, Ref, SyntheticEvent } from "react"; - -import { ThemeCard } from "./ThemeCard"; - -const cl = classNameFactory("vc-settings-theme-"); - -type FileInput = ComponentType<{ - ref: Ref; - onChange: (e: SyntheticEvent) => void; - multiple?: boolean; - filters?: { name?: string; extensions: string[]; }[]; -}>; - -const FileInput: FileInput = findLazy(m => m.prototype?.activateUploadDialogue && m.prototype.setRef); - -// When a local theme is enabled/disabled, update the settings -function onLocalThemeChange(fileName: string, value: boolean) { - if (value) { - if (Settings.enabledThemes.includes(fileName)) return; - Settings.enabledThemes = [...Settings.enabledThemes, fileName]; - } else { - Settings.enabledThemes = Settings.enabledThemes.filter(f => f !== fileName); - } -} - -async function onFileUpload(e: SyntheticEvent) { - e.stopPropagation(); - e.preventDefault(); - - if (!e.currentTarget?.files?.length) return; - const { files } = e.currentTarget; - - const uploads = Array.from(files, file => { - const { name } = file; - if (!name.endsWith(".css")) return; - - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = () => { - VencordNative.themes.uploadTheme(name, reader.result as string) - .then(resolve) - .catch(reject); - }; - reader.readAsText(file); - }); - }); - - await Promise.all(uploads); -} - -export function LocalThemesTab() { - const settings = useSettings(["enabledThemes"]); - - const fileInputRef = useRef(null); - - const [userThemes, setUserThemes] = useState(null); - - useEffect(() => { - refreshLocalThemes(); - }, []); - - async function refreshLocalThemes() { - const themes = await VencordNative.themes.getThemesList(); - setUserThemes(themes); - } - - return ( - <> - - Find Themes: - - - BetterDiscord Themes - - GitHub - - If using the BD site, click on "Download" and place the downloaded .theme.css file into your themes folder. - - - - External Resources - For security reasons, loading resources (styles, fonts, images, ...) from most sites is blocked. - Make sure all your assets are hosted on GitHub, GitLab, Codeberg, Imgur, Discord or Google Fonts. - - - - - <> - {IS_WEB ? - ( - - Upload Theme - { - await onFileUpload(e); - refreshLocalThemes(); - }} - multiple={true} - filters={[{ extensions: ["css"] }]} - /> - - } - Icon={PlusIcon} - /> - ) : ( - VencordNative.themes.openFolder()} - Icon={FolderIcon} - /> - )} - - VencordNative.quickCss.openEditor()} - Icon={PaintbrushIcon} - /> - - {Vencord.Plugins.isPluginEnabled(ClientThemePlugin.name) && ( - openPluginModal(ClientThemePlugin)} - Icon={PencilIcon} - /> - )} - > - - - - {userThemes?.map(theme => ( - onLocalThemeChange(theme.fileName, enabled)} - onDelete={async () => { - onLocalThemeChange(theme.fileName, false); - await VencordNative.themes.deleteTheme(theme.fileName); - refreshLocalThemes(); - }} - theme={theme} - /> - ))} - - - > - ); -} diff --git a/src/components/settings/tabs/themes/OnlineThemesTab.tsx b/src/components/settings/tabs/themes/OnlineThemesTab.tsx deleted file mode 100644 index faca96dcb..000000000 --- a/src/components/settings/tabs/themes/OnlineThemesTab.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { useSettings } from "@api/Settings"; -import { Margins } from "@utils/margins"; -import { classes } from "@utils/misc"; -import { Card, Forms, TextArea, useState } from "@webpack/common"; - -export function OnlineThemesTab() { - const settings = useSettings(["themeLinks"]); - - const [themeText, setThemeText] = useState(settings.themeLinks.join("\n")); - - // When the user leaves the online theme textbox, update the settings - function onBlur() { - settings.themeLinks = [...new Set( - themeText - .trim() - .split(/\n+/) - .map(s => s.trim()) - .filter(Boolean) - )]; - } - - return ( - <> - - - This section is for advanced users. If you are having difficulties using it, use the - Local Themes tab instead. - - - - Paste links to css files here - One link per line - You can prefix lines with @light or @dark to toggle them based on your Discord theme - Make sure to use direct links to files (raw or github.io)! - - - - - - > - ); -} diff --git a/src/components/settings/tabs/themes/ThemeCard.tsx b/src/components/settings/tabs/themes/ThemeCard.tsx deleted file mode 100644 index 5d9b117be..000000000 --- a/src/components/settings/tabs/themes/ThemeCard.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Flex } from "@components/Flex"; -import { DeleteIcon } from "@components/Icons"; -import { Link } from "@components/Link"; -import { AddonCard } from "@components/settings/AddonCard"; -import { UserThemeHeader } from "@main/themes"; -import { openInviteModal } from "@utils/discord"; -import { showToast } from "@webpack/common"; - -interface ThemeCardProps { - theme: UserThemeHeader; - enabled: boolean; - onChange: (enabled: boolean) => void; - onDelete: () => void; -} - -export function ThemeCard({ theme, enabled, onChange, onDelete }: ThemeCardProps) { - return ( - - - - ) - } - footer={ - - {!!theme.website && Website} - {!!(theme.website && theme.invite) && " • "} - {!!theme.invite && ( - { - e.preventDefault(); - theme.invite != null && openInviteModal(theme.invite).catch(() => showToast("Invalid or expired invite")); - }} - > - Discord Server - - )} - - } - /> - ); -} diff --git a/src/components/settings/tabs/themes/index.tsx b/src/components/settings/tabs/themes/index.tsx deleted file mode 100644 index 40653a4c3..000000000 --- a/src/components/settings/tabs/themes/index.tsx +++ /dev/null @@ -1,85 +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 "./styles.css"; - -import { Link } from "@components/Link"; -import { SettingsTab, wrapTab } from "@components/settings/tabs/BaseTab"; -import { getStylusWebStoreUrl } from "@utils/web"; -import { Card, Forms, React, TabBar, useState } from "@webpack/common"; - -import { CspErrorCard } from "./CspErrorCard"; -import { LocalThemesTab } from "./LocalThemesTab"; -import { OnlineThemesTab } from "./OnlineThemesTab"; - -const enum ThemeTab { - LOCAL, - ONLINE -} - -function ThemesTab() { - const [currentTab, setCurrentTab] = useState(ThemeTab.LOCAL); - - return ( - - - - Local Themes - - - Online Themes - - - - - - {currentTab === ThemeTab.LOCAL && } - {currentTab === ThemeTab.ONLINE && } - - ); -} - -function UserscriptThemesTab() { - return ( - - - Themes are not supported on the Userscript! - - - You can instead install themes with the Stylus extension! - - - - ); -} - -export default IS_USERSCRIPT - ? wrapTab(UserscriptThemesTab, "Themes") - : wrapTab(ThemesTab, "Themes"); diff --git a/src/components/settings/tabs/themes/styles.css b/src/components/settings/tabs/themes/styles.css deleted file mode 100644 index b47174063..000000000 --- a/src/components/settings/tabs/themes/styles.css +++ /dev/null @@ -1,52 +0,0 @@ -.vc-settings-theme-grid { - display: grid; - grid-gap: 16px; - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); -} - -.vc-settings-theme-card { - display: flex; - flex-direction: column; - background-color: var(--background-base-lower-alt); - color: var(--interactive-active); - border-radius: 8px; - padding: 1em; - width: 100%; - transition: 0.1s ease-out; - transition-property: box-shadow, transform, background, opacity; -} - -.vc-settings-theme-card-text { - text-overflow: ellipsis; - height: 1.2em; - margin-bottom: 2px; - white-space: nowrap; - overflow: hidden; -} - -.vc-settings-theme-author::before { - content: "by "; -} - -.vc-settings-csp-list { - display: flex; - flex-direction: column; - gap: 8px; -} - -.vc-settings-csp-row { - display: flex; - justify-content: space-between; - align-items: center; - gap: 8px; - - - & a { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - line-height: 1.2em; - } - - --custom-button-button-md-height: 26px; -} diff --git a/src/equicordplugins/soundBoardLogger/settings.tsx b/src/equicordplugins/soundBoardLogger/settings.tsx index 59d7c9917..cf5c3ca5c 100644 --- a/src/equicordplugins/soundBoardLogger/settings.tsx +++ b/src/equicordplugins/soundBoardLogger/settings.tsx @@ -14,7 +14,7 @@ const settings = definePluginSettings({ SavedIds: { description: "The amount of soundboard ids you want to save at a time (0 lets you save infinite)", type: OptionType.COMPONENT, - component: ({ setValue, setError }) => { + component: ({ setValue }) => { const value = settings.store.SavedIds ?? 50; const [state, setState] = useState(`${value}`); const [shouldShowWarning, setShouldShowWarning] = useState(false); @@ -24,7 +24,6 @@ const settings = definePluginSettings({ const changed = Number(newValue); if (Number.isNaN(changed) || changed % 1 !== 0 || changed < 0) { - setError(true); let errorMsg = ""; errorMsg += Number.isNaN(changed) ? "The value is not a number.\n" : ""; errorMsg += (changed % 1 !== 0) ? "The value can't be a decimal number.\n" : ""; @@ -32,7 +31,6 @@ const settings = definePluginSettings({ setErrorMessage(errorMsg); return; } else { - setError(false); setErrorMessage(null); }
https://i.imgur.com/...