diff --git a/src/api/Settings.ts b/src/api/Settings.ts index 73bc9ee6b..2bcc785f9 100644 --- a/src/api/Settings.ts +++ b/src/api/Settings.ts @@ -68,6 +68,7 @@ export interface Settings { plugins: { [plugin: string]: { enabled: boolean; + isFavorite?: boolean; [setting: string]: any; }; }; diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index 47a52a82c..ff89b3f48 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -639,3 +639,31 @@ export function RightArrow(props: IconProps) { ); } + +export function StarFilled(props: IconProps) { + return ( + + + + ); +} + +export function StarOutlined(props: IconProps) { + return ( + + + + ); +} diff --git a/src/components/settings/tabs/plugins/ContributorModal.tsx b/src/components/settings/tabs/plugins/ContributorModal.tsx index 9139fe8f3..9ba303864 100644 --- a/src/components/settings/tabs/plugins/ContributorModal.tsx +++ b/src/components/settings/tabs/plugins/ContributorModal.tsx @@ -13,12 +13,12 @@ import { classNameFactory } from "@utils/css"; import { fetchUserProfile } from "@utils/discord"; import { classes, pluralise } from "@utils/misc"; import { RenderModalProps, User } from "@vencord/discord-types"; -import { Forms, Modal,openModal, showToast, useEffect, useMemo, UserProfileStore, useStateFromStores } from "@webpack/common"; +import { Forms, Modal, openModal, showToast, useEffect, useMemo, UserProfileStore, useStateFromStores } from "@webpack/common"; import Plugins from "~plugins"; -import { GithubButton, WebsiteButton } from "./LinkIconButton"; import { PluginCard } from "./PluginCard"; +import { GithubButton, WebsiteButton } from "./PluginModalButtons"; const cl = classNameFactory("vc-author-modal-"); diff --git a/src/components/settings/tabs/plugins/LinkIconButton.css b/src/components/settings/tabs/plugins/LinkIconButton.css deleted file mode 100644 index 835206381..000000000 --- a/src/components/settings/tabs/plugins/LinkIconButton.css +++ /dev/null @@ -1,13 +0,0 @@ -.vc-settings-modal-link-icon { - height: 32px; - width: 32px; - border-radius: 50%; - border: 4px solid var(--background-base-lowest); - box-sizing: border-box -} - -.vc-settings-modal-links { - display: flex; - gap: 0.2em; - margin-left: auto; -} \ No newline at end of file diff --git a/src/components/settings/tabs/plugins/LinkIconButton.tsx b/src/components/settings/tabs/plugins/LinkIconButton.tsx deleted file mode 100644 index 9f9ecfebb..000000000 --- a/src/components/settings/tabs/plugins/LinkIconButton.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2024 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import "./LinkIconButton.css"; - -import { GithubIcon, WebsiteIcon } from "@components/Icons"; -import { getTheme, Theme } from "@utils/discord"; -import { MaskedLink, Tooltip } from "@webpack/common"; - -export function GithubLinkIcon() { - const theme = getTheme() === Theme.Light ? "#000000" : "#FFFFFF"; - return ; -} - -export function WebsiteLinkIcon() { - const theme = getTheme() === Theme.Light ? "#000000" : "#FFFFFF"; - return ; -} - -interface Props { - text: string; - href: string; -} - -function LinkIcon({ text, href, Icon }: Props & { Icon: React.ComponentType; }) { - return ( - - {props => ( - - - - )} - - ); -} - -export const WebsiteButton = (props: Props) => ; -export const GithubButton = (props: Props) => ; diff --git a/src/components/settings/tabs/plugins/PluginModal.tsx b/src/components/settings/tabs/plugins/PluginModal.tsx index 0e0422c9a..942c552f3 100644 --- a/src/components/settings/tabs/plugins/PluginModal.tsx +++ b/src/components/settings/tabs/plugins/PluginModal.tsx @@ -32,14 +32,14 @@ import { classes } from "@utils/misc"; import { OptionType, Plugin, PluginTag } from "@utils/types"; import { RenderModalProps, User } from "@vencord/discord-types"; import { findCssClassesLazy } from "@webpack"; -import { Clickable, FluxDispatcher, Forms, Modal,openModal, React, Text, Tooltip, useEffect, useMemo, UserStore, UserSummaryItem, UserUtils, useState } from "@webpack/common"; +import { Clickable, FluxDispatcher, Forms, Modal, openModal, React, Text, Tooltip, useEffect, useMemo, UserStore, UserSummaryItem, UserUtils, useState } from "@webpack/common"; import { Constructor } from "type-fest"; import { PluginMeta } from "~plugins"; import { OptionComponentMap } from "./components"; import { openContributorModal } from "./ContributorModal"; -import { GithubButton, WebsiteButton } from "./LinkIconButton"; +import { FavoriteButton, GithubButton, WebsiteButton } from "./PluginModalButtons"; const cl = classNameFactory("vc-plugin-modal-"); @@ -176,6 +176,10 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti {plugin.name} {!pluginMeta.userPlugin && (
+ pluginSettings.isFavorite = !pluginSettings.isFavorite} + /> getTheme() !== Theme.Light ? "dark" : "light"; + +interface Props { + text: string; + href: string; +} + +function LinkIcon({ text, href, Icon }: Props & { Icon: React.ComponentType; }) { + return ( + + {props => + + + + } + + ); +} + +const GithubLinkIcon = () => ; +const WebsiteLinkIcon = () => ; + +export const GithubButton = (props: Props) => ; +export const WebsiteButton = (props: Props) => ; + +export function FavoriteButton({ isFavorite, onClick }: { isFavorite: boolean; onClick: () => void; }) { + const Icon = isFavorite ? StarFilled : StarOutlined; + + return ( + + {props => + + + + } + + ); +} diff --git a/src/components/settings/tabs/plugins/index.tsx b/src/components/settings/tabs/plugins/index.tsx index 69d9a7c08..90ce4311a 100644 --- a/src/components/settings/tabs/plugins/index.tsx +++ b/src/components/settings/tabs/plugins/index.tsx @@ -74,6 +74,7 @@ function ReloadRequiredCard({ required }: { required: boolean; }) { const enum SearchStatus { ALL, + FAVORITES, ENABLED, DISABLED, NEW, @@ -160,7 +161,8 @@ function PluginSettings() { const sortedPlugins = useMemo(() => Object.values(Plugins).sort((a, b) => a.name.localeCompare(b.name)), [] - ); + ) + .toSorted((a, b) => Number(settings.plugins[b.name]?.isFavorite ?? false) - Number(settings.plugins[a.name]?.isFavorite ?? false)); const hasUserPlugins = useMemo(() => !IS_STANDALONE && Object.values(PluginMeta).some(m => m.userPlugin), []); @@ -173,6 +175,9 @@ function PluginSettings() { const { status, tags } = searchValue; switch (status) { + case SearchStatus.FAVORITES: + if (!settings.plugins[plugin.name]?.isFavorite) return false; + break; case SearchStatus.DISABLED: if (isPluginEnabled(plugin.name)) return false; break; @@ -288,6 +293,7 @@ function PluginSettings() {