diff --git a/packages/discord-types/src/menu.d.ts b/packages/discord-types/src/menu.d.ts index d083dc906..9235d31c6 100644 --- a/packages/discord-types/src/menu.d.ts +++ b/packages/discord-types/src/menu.d.ts @@ -1,11 +1,14 @@ import type { ComponentType, CSSProperties, ForwardRefRenderFunction, MouseEvent, PropsWithChildren, ReactNode, UIEvent } from "react"; +import { LiteralUnion } from "type-fest"; type RC = ComponentType>>; -type LeadingAccessory = +type Accessory = | { type: "icon"; icon: ComponentType; + color?: string; + size?: LiteralUnion<"refresh_sm", string>; } | { type: "emoji"; @@ -36,7 +39,7 @@ export interface Menu { label: ReactNode; action?(e: MouseEvent): void; icon?: ComponentType; - leadingAccessory?: LeadingAccessory; + leadingAccessory?: Accessory; color?: string; render?: ComponentType; diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index ff89b3f48..008a7a893 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -640,6 +640,20 @@ export function RightArrow(props: IconProps) { ); } +export function TopRightArrow(props: IconProps) { + return ( + + + + ); +} + export function StarFilled(props: IconProps) { return ( ); } + +export function SearchIcon(props: IconProps) { + return ( + + + + ); +} + +export function EyeIcon(props: IconProps) { + return ( + + + + ); +} diff --git a/src/plugins/_api/badges/index.tsx b/src/plugins/_api/badges/index.tsx index 2bdefa97b..d91b4eae7 100644 --- a/src/plugins/_api/badges/index.tsx +++ b/src/plugins/_api/badges/index.tsx @@ -22,6 +22,7 @@ import { _getBadges, BadgePosition, BadgeUserArgs, ProfileBadge } from "@api/Bad import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { Heart } from "@components/Heart"; +import { CopyIcon, LinkIcon } from "@components/Icons"; import DonateButton from "@components/settings/DonateButton"; import { openContributorModal } from "@components/settings/tabs"; import { Devs } from "@utils/constants"; @@ -68,6 +69,7 @@ function BadgeContextMenu({ badge }: { badge: Omit & BadgeUs id="vc-badge-copy-name" label="Copy Badge Name" action={() => copyWithToast(badge.description!)} + leadingAccessory={{ type: "icon", icon: CopyIcon }} /> )} {badge.iconSrc && ( @@ -75,6 +77,7 @@ function BadgeContextMenu({ badge }: { badge: Omit & BadgeUs id="vc-badge-copy-link" label="Copy Badge Image Link" action={() => copyWithToast(badge.iconSrc!)} + leadingAccessory={{ type: "icon", icon: LinkIcon }} /> )} diff --git a/src/plugins/betterRoleContext/index.tsx b/src/plugins/betterRoleContext/index.tsx index e45183ff7..9b5653aef 100644 --- a/src/plugins/betterRoleContext/index.tsx +++ b/src/plugins/betterRoleContext/index.tsx @@ -150,6 +150,7 @@ export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutR {...popoutProps} >
View Role Members
+ {/* FIXME: update to new icon style */}
diff --git a/src/plugins/copyEmojiMarkdown/index.tsx b/src/plugins/copyEmojiMarkdown/index.tsx index dfa46a350..8b8fd38db 100644 --- a/src/plugins/copyEmojiMarkdown/index.tsx +++ b/src/plugins/copyEmojiMarkdown/index.tsx @@ -5,6 +5,7 @@ */ import { definePluginSettings } from "@api/Settings"; +import { CopyIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import { copyWithToast } from "@utils/discord"; import definePlugin, { OptionType } from "@utils/types"; @@ -69,6 +70,7 @@ export default definePlugin({ "Success! Copied emoji markdown." ); }} + leadingAccessory={{ type: "icon", icon: CopyIcon }} /> ); }, diff --git a/src/plugins/copyStickerLinks/index.tsx b/src/plugins/copyStickerLinks/index.tsx index 530f19509..2e3d3ed69 100644 --- a/src/plugins/copyStickerLinks/index.tsx +++ b/src/plugins/copyStickerLinks/index.tsx @@ -18,6 +18,7 @@ import { NavContextMenuPatchCallback } from "@api/ContextMenu"; import { isPluginEnabled } from "@api/PluginManager"; +import { LinkIcon, TopRightArrow } from "@components/Icons"; import ExpressionClonerPlugin from "@plugins/expressionCloner"; import { Devs } from "@utils/constants"; import { copyWithToast } from "@utils/discord"; @@ -43,14 +44,17 @@ function buildMenuItem(sticker: PartialSticker, addBottomSeparator: boolean) { copyWithToast(getUrl(sticker), "Link copied!")} /> VencordNative.native.openExternal(getUrl(sticker))} /> diff --git a/src/plugins/expressionCloner/index.tsx b/src/plugins/expressionCloner/index.tsx index 9f99cc15e..57bde0457 100644 --- a/src/plugins/expressionCloner/index.tsx +++ b/src/plugins/expressionCloner/index.tsx @@ -21,6 +21,7 @@ import { migratePluginSettings } from "@api/Settings"; import { BaseText } from "@components/BaseText"; import { CheckedTextInput } from "@components/CheckedTextInput"; import { Flex } from "@components/Flex"; +import { PlusIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import { getGuildAcronym, hasGuildFeature } from "@utils/discord"; import { Logger } from "@utils/Logger"; @@ -327,6 +328,7 @@ function buildMenuItem(type: "Emoji" | "Sticker", fetchData: () => Promisable openModalLazy(async () => { const res = await fetchData(); diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx index 130f0c9b5..b598b7e5e 100644 --- a/src/plugins/messageLogger/index.tsx +++ b/src/plugins/messageLogger/index.tsx @@ -23,6 +23,7 @@ import { updateMessage } from "@api/MessageUpdater"; import { definePluginSettings } from "@api/Settings"; import { disableStyle, enableStyle } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; +import { DeleteIcon, EyeIcon } from "@components/Icons"; import { Devs, SUPPORT_CATEGORY_ID, VENBOT_USER_ID } from "@utils/constants"; import { getIntlMessage } from "@utils/discord"; import { Logger } from "@utils/Logger"; @@ -176,6 +177,7 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = id={TOGGLE_DELETE_STYLE_ID} key={TOGGLE_DELETE_STYLE_ID} label="Toggle Deleted Highlight" + leadingAccessory={{ type: "icon", icon: EyeIcon }} action={() => domElement.classList.toggle("messagelogger-deleted")} /> )); @@ -186,6 +188,7 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = id={REMOVE_HISTORY_ID} key={REMOVE_HISTORY_ID} label="Remove Message History" + leadingAccessory={{ type: "icon", icon: DeleteIcon }} color="danger" action={() => { clearMessageHistory(message); diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index 9279b0dd7..45897547a 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -271,6 +271,7 @@ function UserContextMenu({ userId }: { userId: string; }) { { copyToClipboard(userId); }} diff --git a/src/plugins/permissionsViewer/index.tsx b/src/plugins/permissionsViewer/index.tsx index b8b011b73..54d9135fd 100644 --- a/src/plugins/permissionsViewer/index.tsx +++ b/src/plugins/permissionsViewer/index.tsx @@ -59,13 +59,14 @@ export const settings = definePluginSettings({ }, }); -function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { +function MenuItem(guildId: string, { id, type, withIcon }: { id?: string, type?: MenuItemParentType, withIcon?: boolean; }) { if (type === MenuItemParentType.User && !GuildMemberStore.isMember(guildId, id!)) return null; return ( { const guild = GuildStore.getGuild(guildId); @@ -125,7 +126,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) { ); } -function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentType): NavContextMenuPatchCallback { +function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentType, withIcon = false): NavContextMenuPatchCallback { return (children, props) => { if ( !props || @@ -139,9 +140,9 @@ function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentT const group = findGroupChildrenByChildId(childId, children); const item = match(type) - .with(MenuItemParentType.User, () => MenuItem(props.guildId, props.user.id, type)) - .with(MenuItemParentType.Channel, () => MenuItem(props.guild.id, props.channel.id, type)) - .with(MenuItemParentType.Guild, () => MenuItem(props.guild.id)) + .with(MenuItemParentType.User, () => MenuItem(props.guildId, { id: props.user.id, type, withIcon })) + .with(MenuItemParentType.Channel, () => MenuItem(props.guild.id, { id: props.channel.id, type, withIcon })) + .with(MenuItemParentType.Guild, () => MenuItem(props.guild.id, { withIcon })) .otherwise(() => null); if (item == null) return; @@ -214,6 +215,6 @@ export default definePlugin({ "user-context": makeContextMenuPatch("roles", MenuItemParentType.User), "channel-context": makeContextMenuPatch(["mute-channel", "unmute-channel"], MenuItemParentType.Channel), "guild-context": makeContextMenuPatch("privacy", MenuItemParentType.Guild), - "guild-header-popout": makeContextMenuPatch("privacy", MenuItemParentType.Guild) + "guild-header-popout": makeContextMenuPatch("privacy", MenuItemParentType.Guild, true) } }); diff --git a/src/plugins/previewMessage/index.tsx b/src/plugins/previewMessage/index.tsx index 4d2aa89c3..285376ad4 100644 --- a/src/plugins/previewMessage/index.tsx +++ b/src/plugins/previewMessage/index.tsx @@ -18,6 +18,7 @@ import { ChatBarButton, ChatBarButtonFactory } from "@api/ChatButtons"; import { generateId, sendBotMessage } from "@api/Commands"; +import { EyeIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin, { IconComponent, StartAt } from "@utils/types"; import { CloudUpload, MessageAttachment } from "@vencord/discord-types"; @@ -75,17 +76,12 @@ const getAttachments = async (channelId: string) => const PreviewIcon: IconComponent = ({ height = 20, width = 20, className }) => { return ( - - - + /> ); }; diff --git a/src/plugins/replaceGoogleSearch/index.tsx b/src/plugins/replaceGoogleSearch/index.tsx index 223a2dd0f..96d11f87d 100644 --- a/src/plugins/replaceGoogleSearch/index.tsx +++ b/src/plugins/replaceGoogleSearch/index.tsx @@ -6,7 +6,7 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; import { definePluginSettings } from "@api/Settings"; -import { Flex } from "@components/Flex"; +import { SearchIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; import { Menu } from "@webpack/common"; @@ -89,6 +89,7 @@ function makeSearchItem(src: string) { label="Search Text" key="search-text" id="vc-search-text" + leadingAccessory={{ type: "icon", icon: SearchIcon }} > {Object.keys(Engines).map(engine => { const key = "vc-search-content-" + engine; @@ -96,20 +97,8 @@ function makeSearchItem(src: string) { - - {engine} - - } + label={engine} + leadingAccessory={{ type: "image", src: `https://icons.duckduckgo.com/ip3/${new URL(Engines[engine]).hostname}.ico` }} action={() => search(src, Engines[engine])} /> ); diff --git a/src/plugins/reverseImageSearch/index.tsx b/src/plugins/reverseImageSearch/index.tsx index 68845c0a1..1ecdf864d 100644 --- a/src/plugins/reverseImageSearch/index.tsx +++ b/src/plugins/reverseImageSearch/index.tsx @@ -17,8 +17,7 @@ */ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; -import { Flex } from "@components/Flex"; -import { OpenExternalIcon } from "@components/Icons"; +import { OpenExternalIcon, SearchIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { Menu } from "@webpack/common"; @@ -43,6 +42,7 @@ function makeSearchItem(src: string) { label="Search Image" key="search-image" id="search-image" + leadingAccessory={{ type: "icon", icon: SearchIcon }} > {Object.keys(Engines).map((engine, i) => { const key = "search-image-" + engine; @@ -50,20 +50,8 @@ function makeSearchItem(src: string) { - - {engine} - - } + label={engine} + leadingAccessory={{ type: "image", src: `https://icons.duckduckgo.com/ip3/${new URL(Engines[engine]).host}.ico` }} action={() => search(src, Engines[engine])} /> ); @@ -71,12 +59,8 @@ function makeSearchItem(src: string) { - - All - - } + label="All" + leadingAccessory={{ type: "icon", icon: OpenExternalIcon }} action={() => Object.values(Engines).forEach(e => search(src, e))} /> diff --git a/src/plugins/serverInfo/index.tsx b/src/plugins/serverInfo/index.tsx index 5a6f51c31..5afdaf7c3 100644 --- a/src/plugins/serverInfo/index.tsx +++ b/src/plugins/serverInfo/index.tsx @@ -5,6 +5,7 @@ */ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { InfoIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; import { Guild } from "@vencord/discord-types"; @@ -12,13 +13,14 @@ import { Menu } from "@webpack/common"; import { openGuildInfoModal } from "./GuildInfoModal"; -const Patch: NavContextMenuPatchCallback = (children, { guild }: { guild: Guild; }) => { +const makePatch: (showIcon: boolean) => NavContextMenuPatchCallback = showIcon => (children, { guild }: { guild: Guild; }) => { const group = findGroupChildrenByChildId("privacy", children); group?.push( openGuildInfoModal(guild)} /> ); @@ -33,7 +35,7 @@ export default definePlugin({ searchTerms: ["guild", "info", "ServerProfile"], contextMenus: { - "guild-context": Patch, - "guild-header-popout": Patch + "guild-context": makePatch(false), + "guild-header-popout": makePatch(true) } });