From e8e83bf2eb0d4152a8286b944e69bc5347717109 Mon Sep 17 00:00:00 2001
From: vMohammad24 <62218284+vMohammad24@users.noreply.github.com>
Date: Fri, 30 May 2025 18:54:06 +0300
Subject: [PATCH] fixed and added custom folder icons by sadan
---
.../customFolderIcons/README.md | 14 ++
.../customFolderIcons/components.tsx | 124 ++++++++++++++++++
.../customFolderIcons/index.tsx | 58 ++++++++
.../customFolderIcons/settings.tsx | 29 ++++
.../customFolderIcons/util.tsx | 29 ++++
5 files changed, 254 insertions(+)
create mode 100644 src/equicordplugins/customFolderIcons/README.md
create mode 100644 src/equicordplugins/customFolderIcons/components.tsx
create mode 100644 src/equicordplugins/customFolderIcons/index.tsx
create mode 100644 src/equicordplugins/customFolderIcons/settings.tsx
create mode 100644 src/equicordplugins/customFolderIcons/util.tsx
diff --git a/src/equicordplugins/customFolderIcons/README.md b/src/equicordplugins/customFolderIcons/README.md
new file mode 100644
index 00000000..9b67e4eb
--- /dev/null
+++ b/src/equicordplugins/customFolderIcons/README.md
@@ -0,0 +1,14 @@
+# CustomFolderIcons
+
+Allows you to set custom images/svgs as folder icons
+
+Available as "Change Icon" in the folder context menu
+
+
+
+
+
+
+
+
+
diff --git a/src/equicordplugins/customFolderIcons/components.tsx b/src/equicordplugins/customFolderIcons/components.tsx
new file mode 100644
index 00000000..f641a20e
--- /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 settings, { folderIconsData } 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..45171700
--- /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 settings, { folderIconsData } from "./settings";
+import { folderProp, int2rgba } from "./util";
+
+export default definePlugin({
+ settings,
+ name: "CustomFolderIcons",
+ description: "Customize folder icons with any png",
+ authors: [EquicordDevs.sadan],
+ patches: [
+ {
+ find: ".folderButtonInner",
+ replacement: {
+ match: /(\(0,r\.jsx\)\("div",\{className:f\.folderButtonInner,children:null!=O\?\(0,r\.jsx\)\("div",\{className:f\.folderIconWrapper,children:O\}\):)(\(0,r\.jsx\)\(m,\{folderNode:l,hovered:I,sorting:s\}\))/,
+ replace: "$1($self.shouldReplace({folderNode:l})?$self.replace({folderNode:l}):$2)"
+ }
+ },
+ ],
+ 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..dbe15526
--- /dev/null
+++ b/src/equicordplugins/customFolderIcons/settings.tsx
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+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: () => <>>
+ }
+});
+export default settings;
diff --git a/src/equicordplugins/customFolderIcons/util.tsx b/src/equicordplugins/customFolderIcons/util.tsx
new file mode 100644
index 00000000..3c49e2ea
--- /dev/null
+++ b/src/equicordplugins/customFolderIcons/util.tsx
@@ -0,0 +1,29 @@
+/*
+ * Vencord, a Discord client mod
+ * Copyright (c) 2024 sadan
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+import settings, { folderIcon, folderIconsData } 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})`;
+}