diff --git a/README.md b/README.md index 92ba6668..3bfac801 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch ### Extra included plugins
-182 additional plugins +183 additional plugins ### All Platforms @@ -41,6 +41,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch - CommandPalette by Ethan - CopyStickerLinks by Byeoon - CopyUserMention by Cortex & castdrian +- CustomFolderIcons by sadan - CustomSounds by TheKodeToad & SpikeHD - CustomTimestamps by Rini & nvhrr - CustomUserColors by mochienya diff --git a/src/equicordplugins/customFolderIcons/components.tsx b/src/equicordplugins/customFolderIcons/components.tsx new file mode 100644 index 00000000..b5feb52a --- /dev/null +++ b/src/equicordplugins/customFolderIcons/components.tsx @@ -0,0 +1,124 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 sadan + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { closeModal, ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal"; +import { Button, Menu, Slider, TextInput, useState } from "@webpack/common"; + +import { folderIconsData, settings } from "./settings"; +import { folderProp, int2rgba, setFolderData } from "./util"; + +export function ImageModal(folderProps: folderProp) { + const [data, setData] = useState(((settings.store.folderIcons ?? {}) as folderIconsData)[folderProps.folderId]?.url ?? ""); + const [size, setSize] = useState(100); + return ( + <> + { + setData(val); + }} + placeholder="https://example.com/image.png" + > + + + {data && <> +
Change the size of the folder icon
+ { + setSize(v); + }} + maxValue={200} + minValue={25} + // [25, 200] + markers={Array.apply(0, Array(176)).map((_, i) => i + 25)} + stickToMarkers={true} + keyboardStep={1} + renderMarker={() => null} /> + } + +
+ +
+ + ); +} +export function RenderPreview({ folderProps, url, size }: { folderProps: folderProp; url: string; size: number; }) { + if (!url) return null; + return ( +
+ +
+ ); +} + +export function makeContextItem(a: folderProp) { + return ( + { + openModalLazy(async () => { + return props => ( + + +
+ Set a New Icon. +
+
+ + + +
+ You might have to hover the folder after setting in order for it to refresh. +
+
+ ); + }, + { + modalKey: "custom-folder-icon" + }); + }} /> + ); +} diff --git a/src/equicordplugins/customFolderIcons/index.tsx b/src/equicordplugins/customFolderIcons/index.tsx new file mode 100644 index 00000000..5da72533 --- /dev/null +++ b/src/equicordplugins/customFolderIcons/index.tsx @@ -0,0 +1,58 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 sadan + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { EquicordDevs } from "@utils/constants"; +import definePlugin from "@utils/types"; + +import { makeContextItem } from "./components"; +import { folderIconsData, settings } from "./settings"; +import { folderProp, int2rgba } from "./util"; + +export default definePlugin({ + name: "CustomFolderIcons", + description: "Customize folder icons with any png", + authors: [EquicordDevs.sadan], + settings, + patches: [ + { + find: ".folderButtonInner", + replacement: { + match: /(\(0,\i\.jsx\)\(\i,\{folderNode:(\i),hovered:\i,sorting:\i\}\))/, + replace: "($self.shouldReplace({folderNode:$2})?$self.replace({folderNode:$2}):$1)" + } + }, + ], + contextMenus: { + "guild-context": (menuItems, props: folderProp) => { + if (!("folderId" in props)) return; + menuItems.push(makeContextItem(props)); + } + }, + shouldReplace(props: any): boolean { + return !!((settings.store.folderIcons as folderIconsData)?.[props.folderNode.id]?.url); + }, + replace(props: any) { + const folderSettings = (settings.store.folderIcons as folderIconsData); + if (folderSettings && folderSettings[props.folderNode.id]) { + const data = folderSettings[props.folderNode.id]; + return ( +
+ +
+ ); + } + } +}); diff --git a/src/equicordplugins/customFolderIcons/settings.tsx b/src/equicordplugins/customFolderIcons/settings.tsx new file mode 100644 index 00000000..83c98e76 --- /dev/null +++ b/src/equicordplugins/customFolderIcons/settings.tsx @@ -0,0 +1,28 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 sadan + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { definePluginSettings } from "@api/Settings"; +import { OptionType } from "@utils/types"; + +export interface folderIcon { + url: string, + size: number, +} +export type folderIconsData = Record; + +export const settings = definePluginSettings({ + solidIcon: { + type: OptionType.BOOLEAN, + default: false, + description: "Use a solid background on the background of the image" + }, + folderIcons: { + type: OptionType.COMPONENT, + hidden: true, + description: "folder icon settings", + component: () => <> + } +}); diff --git a/src/equicordplugins/customFolderIcons/util.tsx b/src/equicordplugins/customFolderIcons/util.tsx new file mode 100644 index 00000000..959b35fb --- /dev/null +++ b/src/equicordplugins/customFolderIcons/util.tsx @@ -0,0 +1,31 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 sadan + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { folderIcon, folderIconsData, settings } from "./settings"; + +export async function setFolderData(props: folderProp, newData: folderIcon) { + if (!settings.store.folderIcons) { + settings.store.folderIcons = {}; + } + const folderSettings = (settings.store.folderIcons as folderIconsData); + folderSettings[props.folderId] = newData; +} + +export interface folderProp { + folderId: string; + folderColor: number; +} + +/** + * @param rgbVal RGB value + * @param alpha alpha bewteen zero and 1 +*/ +export function int2rgba(rgbVal: number, alpha: number = 1) { + const b = rgbVal & 0xFF, + g = (rgbVal & 0xFF00) >>> 8, + r = (rgbVal & 0xFF0000) >>> 16; + return `rgba(${[r, g, b].join(",")},${alpha})`; +}