diff --git a/src/plugins/anonymiseFileNames/index.ts b/src/plugins/anonymiseFileNames/index.ts
deleted file mode 100644
index 9e69d7a9..00000000
--- a/src/plugins/anonymiseFileNames/index.ts
+++ /dev/null
@@ -1,94 +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 { Settings } from "@api/Settings";
-import { Devs } from "@utils/constants";
-import definePlugin, { OptionType } from "@utils/types";
-
-const enum Methods {
- Random,
- Consistent,
- Timestamp,
-}
-
-const tarExtMatcher = /\.tar\.\w+$/;
-
-export default definePlugin({
- name: "AnonymiseFileNames",
- authors: [Devs.obscurity],
- description: "Anonymise uploaded file names",
- patches: [
- {
- find: "instantBatchUpload:function",
- replacement: {
- match: /uploadFiles:(.{1,2}),/,
- replace:
- "uploadFiles:(...args)=>(args[0].uploads.forEach(f=>f.filename=$self.anonymise(f.filename)),$1(...args)),",
- },
- },
- ],
-
- options: {
- method: {
- description: "Anonymising method",
- type: OptionType.SELECT,
- options: [
- { label: "Random Characters", value: Methods.Random, default: true },
- { label: "Consistent", value: Methods.Consistent },
- { label: "Timestamp (4chan-like)", value: Methods.Timestamp },
- ],
- },
- randomisedLength: {
- description: "Random characters length",
- type: OptionType.NUMBER,
- default: 7,
- disabled: () => Settings.plugins.AnonymiseFileNames.method !== Methods.Random,
- },
- consistent: {
- description: "Consistent filename",
- type: OptionType.STRING,
- default: "image",
- disabled: () => Settings.plugins.AnonymiseFileNames.method !== Methods.Consistent,
- },
- },
-
- anonymise(file: string) {
- let name = "image";
- const tarMatch = tarExtMatcher.exec(file);
- const extIdx = tarMatch?.index ?? file.lastIndexOf(".");
- const ext = extIdx !== -1 ? file.slice(extIdx) : "";
-
- switch (Settings.plugins.AnonymiseFileNames.method) {
- case Methods.Random:
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- name = Array.from(
- { length: Settings.plugins.AnonymiseFileNames.randomisedLength },
- () => chars[Math.floor(Math.random() * chars.length)]
- ).join("");
- break;
- case Methods.Consistent:
- name = Settings.plugins.AnonymiseFileNames.consistent;
- break;
- case Methods.Timestamp:
- // UNIX timestamp in nanos, i could not find a better dependency-less way
- name = `${Math.floor(Date.now() / 1000)}${Math.floor(window.performance.now())}`;
- break;
- }
- return name + ext;
- },
-});
diff --git a/src/plugins/anonymiseFileNames/index.tsx b/src/plugins/anonymiseFileNames/index.tsx
new file mode 100644
index 00000000..845aa756
--- /dev/null
+++ b/src/plugins/anonymiseFileNames/index.tsx
@@ -0,0 +1,130 @@
+/*
+ * 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 { Upload } from "@api/MessageEvents";
+import { definePluginSettings } from "@api/Settings";
+import ErrorBoundary from "@components/ErrorBoundary";
+import { Devs } from "@utils/constants";
+import definePlugin, { OptionType } from "@utils/types";
+import { findByCodeLazy, findByPropsLazy } from "@webpack";
+
+type AnonUpload = Upload & { anonymise?: boolean; };
+
+const ActionBarIcon = findByCodeLazy(".actionBarIcon)");
+const UploadDraft = findByPropsLazy("popFirstFile", "update");
+
+const enum Methods {
+ Random,
+ Consistent,
+ Timestamp,
+}
+
+const tarExtMatcher = /\.tar\.\w+$/;
+
+const settings = definePluginSettings({
+ anonymiseByDefault: {
+ description: "Whether to anonymise file names by default",
+ type: OptionType.BOOLEAN,
+ default: true,
+ },
+ method: {
+ description: "Anonymising method",
+ type: OptionType.SELECT,
+ options: [
+ { label: "Random Characters", value: Methods.Random, default: true },
+ { label: "Consistent", value: Methods.Consistent },
+ { label: "Timestamp", value: Methods.Timestamp },
+ ],
+ },
+ randomisedLength: {
+ description: "Random characters length",
+ type: OptionType.NUMBER,
+ default: 7,
+ disabled: () => settings.store.method !== Methods.Random,
+ },
+ consistent: {
+ description: "Consistent filename",
+ type: OptionType.STRING,
+ default: "image",
+ disabled: () => settings.store.method !== Methods.Consistent,
+ },
+});
+
+export default definePlugin({
+ name: "AnonymiseFileNames",
+ authors: [Devs.obscurity],
+ description: "Anonymise uploaded file names",
+ patches: [
+ {
+ find: "instantBatchUpload:function",
+ replacement: {
+ match: /uploadFiles:(.{1,2}),/,
+ replace:
+ "uploadFiles:(...args)=>(args[0].uploads.forEach(f=>f.filename=$self.anonymise(f)),$1(...args)),",
+ },
+ },
+ {
+ find: ".Messages.ATTACHMENT_UTILITIES_SPOILER",
+ replacement: {
+ match: /(?<=children:\[)(?=.{10,80}tooltip:\i\.\i\.Messages\.ATTACHMENT_UTILITIES_SPOILER)/,
+ replace: "arguments[0].canEdit!==false?$self.renderIcon(arguments[0]):null,"
+ },
+ },
+ ],
+ settings,
+
+ renderIcon: ErrorBoundary.wrap(({ upload, channelId, draftType }: { upload: AnonUpload; draftType: unknown; channelId: string; }) => {
+ const anonymise = upload.anonymise ?? settings.store.anonymiseByDefault;
+ return (
+ {
+ upload.anonymise = !anonymise;
+ UploadDraft.update(channelId, upload.id, draftType, {}); // dummy update so component rerenders
+ }}
+ >
+ {anonymise
+ ?
+ :
+ }
+
+ );
+ }, { noop: true }),
+
+ anonymise(upload: AnonUpload) {
+ if ((upload.anonymise ?? settings.store.anonymiseByDefault) === false) return upload.filename;
+
+ const file = upload.filename;
+ const tarMatch = tarExtMatcher.exec(file);
+ const extIdx = tarMatch?.index ?? file.lastIndexOf(".");
+ const ext = extIdx !== -1 ? file.slice(extIdx) : "";
+
+ switch (settings.store.method) {
+ case Methods.Random:
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ return Array.from(
+ { length: settings.store.randomisedLength },
+ () => chars[Math.floor(Math.random() * chars.length)]
+ ).join("") + ext;
+ case Methods.Consistent:
+ return settings.store.consistent + ext;
+ case Methods.Timestamp:
+ return Date.now() + ext;
+ }
+ },
+});