From f6baa8dcfbc549ed188b0ba1270c76d1da28312a Mon Sep 17 00:00:00 2001
From: kmmiio99o <164557248+kmmiio99o@users.noreply.github.com>
Date: Sat, 27 Sep 2025 19:40:15 +0200
Subject: [PATCH] Add plugin-list and theme-list commands with detailed options
---
package.json | 52 +++---
plugins/all-in-one/index.ts | 273 +++++++++++++++++++++++++++++---
plugins/all-in-one/settings.tsx | 145 +++++++++--------
3 files changed, 354 insertions(+), 116 deletions(-)
diff --git a/package.json b/package.json
index a4d53bb..750821e 100644
--- a/package.json
+++ b/package.json
@@ -1,27 +1,29 @@
{
- "scripts": {
- "build": "node build.mjs",
- "watch": "node build.mjs -w",
- "lint": "eslint plugins",
- "make": "node make.mjs"
- },
- "devDependencies": {
- "@rollup/plugin-commonjs": "^24.1.0",
- "@rollup/plugin-node-resolve": "^15.0.2",
- "@swc/core": "^1.3.51",
- "@types/react": "^18.0.37",
- "@types/react-native": "^0.70.13",
- "@typescript-eslint/eslint-plugin": "^5.59.0",
- "@typescript-eslint/parser": "^5.59.0",
- "esbuild": "^0.17.17",
- "eslint": "^8.38.0",
- "eslint-plugin-react": "^7.32.2",
- "rollup": "^3.20.6",
- "rollup-plugin-esbuild": "^5.0.0",
- "typescript": "^4.9.5",
- "vendetta-types": "^2.4.18"
- },
- "dependencies": {
- "@swc/helpers": "^0.5.0"
- }
+ "scripts": {
+ "build": "node build.mjs",
+ "watch": "node build.mjs -w",
+ "lint": "eslint plugins",
+ "make": "node make.mjs",
+ "serve": "node serve.mjs"
+ },
+ "devDependencies": {
+ "@rollup/plugin-commonjs": "^24.1.0",
+ "@rollup/plugin-node-resolve": "^15.0.2",
+ "@swc/core": "^1.3.51",
+ "@types/react": "^18.0.37",
+ "@types/react-native": "^0.70.13",
+ "@typescript-eslint/eslint-plugin": "^5.59.0",
+ "@typescript-eslint/parser": "^5.59.0",
+ "esbuild": "^0.17.17",
+ "eslint": "^8.38.0",
+ "eslint-plugin-react": "^7.32.2",
+ "rollup": "^3.20.6",
+ "rollup-plugin-esbuild": "^5.0.0",
+ "typescript": "^4.9.5",
+ "vendetta-types": "^2.4.18"
+ },
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "serve": "^14.2.5"
+ }
}
diff --git a/plugins/all-in-one/index.ts b/plugins/all-in-one/index.ts
index e8c6549..eb860b7 100644
--- a/plugins/all-in-one/index.ts
+++ b/plugins/all-in-one/index.ts
@@ -1,27 +1,30 @@
import { registerCommand } from "@vendetta/commands";
import { findByStoreName, findByProps } from "@vendetta/metro";
import { storage } from "@vendetta/plugin";
+import { themes } from "@vendetta/themes";
+import { plugins } from "@vendetta/plugins";
+import { alerts } from "@vendetta/ui";
import settings from "./settings";
const UserStore = findByStoreName("UserStore");
const MessageActions = findByProps("sendMessage");
+const Clyde = findByProps("sendBotMessage");
+
+const maxMessageLength =
+ UserStore.getCurrentUser()?.premiumType === 2 ? 4000 : 2000;
let commands: Array<() => void> = [];
-// Initialize storage with default values if not set
-if (!storage.factSettings) {
- storage.factSettings = {
- sendAsReply: true,
- includeCitation: false,
- };
-}
+// Constants
+const STATUS = {
+ ENABLED: "🟢",
+ DISABLED: "🔴",
+ SELECTED: "🔶",
+ NOT_SELECTED: "🔷",
+} as const;
-if (!storage.listSettings) {
- storage.listSettings = {
- pluginListAlwaysDetailed: false,
- themeListAlwaysDetailed: false,
- };
-}
+const SPLIT_LARGE_MESSAGES_PLUGIN =
+ "https://vd-plugins.github.io/proxy/actuallythesun.github.io/vendetta-plugins/SplitLargeMessages/";
// API Functions
const uselessFact = async () => {
@@ -61,16 +64,15 @@ async function getPetPetData(image: string) {
return body;
}
-// Helper function to format fact response
+// Helper Functions
const formatFactResponse = (fact: { text: string; source?: string }) => {
let response = fact.text;
- if (storage.factSettings.includeCitation && fact.source) {
+ if (storage.factSettings?.includeCitation && fact.source) {
response += `\n\nSource: ${fact.source}`;
}
return response;
};
-// Helper function to send message
const sendMessage = (
channelId: string,
content: string,
@@ -79,17 +81,173 @@ const sendMessage = (
const fixNonce = Date.now().toString();
const message = {
content,
- ...(replyToId && storage.factSettings.sendAsReply
+ ...(replyToId && storage.factSettings?.sendAsReply
? { messageReference: { messageId: replyToId } }
: {}),
};
- MessageActions.sendMessage(channelId, message, undefined, {
- nonce: fixNonce,
- });
+
+ MessageActions.sendMessage(channelId, message, void 0, { nonce: fixNonce });
return { type: 4 }; // Acknowledge the command
};
-// Command Definitions
+const addonAuthors = (authors: Array<{ name: string }>) =>
+ authors.map((author) => author.name).join(", ");
+
+const formatList = (list: string[]) => list.join("\n").trimEnd();
+
+const getListLength = (list: string[]) => formatList(list).length;
+
+const sendList = async (channelID: string, list: string[]) => {
+ const fixNonce = Date.now().toString();
+ await MessageActions.sendMessage(
+ channelID,
+ { content: formatList(list) },
+ void 0,
+ { nonce: fixNonce },
+ );
+};
+
+const isSLMPluginInstalled = () =>
+ Object.keys(plugins).includes(SPLIT_LARGE_MESSAGES_PLUGIN);
+
+const isSLMPluginEnabled = () => {
+ const plugin = Object.values(plugins).find(
+ (p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN,
+ );
+ return plugin?.enabled ?? false;
+};
+
+// Command Handlers
+async function handleThemeList(detailed: boolean, ctx: any) {
+ const alwaysDetailed = storage.themeListAlwaysDetailed ?? false;
+ const themeList = [
+ `**My Theme List | ${Object.keys(themes).length} Themes**`,
+ "",
+ ];
+
+ const themeValues = Object.values(themes);
+ if (themeValues.length) {
+ for (const theme of themeValues) {
+ const { selected, data, id } = theme;
+ const { name, description, authors } = data;
+
+ if (detailed || alwaysDetailed) {
+ themeList.push(
+ `> **Name**: ${name}`,
+ `> **Selected**: ${selected ? STATUS.SELECTED : STATUS.NOT_SELECTED}`,
+ `> **Description**: ${description}`,
+ `> **Authors**: ${addonAuthors(authors)}`,
+ `> **[Install!](${id})**`,
+ "",
+ );
+ } else {
+ themeList.push(
+ `> ${selected ? STATUS.SELECTED : STATUS.NOT_SELECTED} **${name}** by ${addonAuthors(authors)}`,
+ );
+ }
+ }
+ } else {
+ themeList.push("Nothing to see here, huh...");
+ }
+
+ const isListTooLong = getListLength(themeList) > maxMessageLength;
+
+ if (isListTooLong && !isSLMPluginInstalled()) {
+ const fixNonce = Date.now().toString();
+ Clyde.sendBotMessage(
+ ctx.channel.id,
+ `Your list is too long to send it! Please install the [Split Large Messages](${SPLIT_LARGE_MESSAGES_PLUGIN}) plugin.`,
+ void 0,
+ { nonce: fixNonce },
+ );
+ return { type: 4 };
+ } else if (isListTooLong && !isSLMPluginEnabled()) {
+ const fixNonce = Date.now().toString();
+ Clyde.sendBotMessage(
+ ctx.channel.id,
+ "Your list is too long to send it! You have the Split Large Messages plugin installed, but it's not enabled!\n> Please enable it in order to send the list.",
+ void 0,
+ { nonce: fixNonce },
+ );
+ return { type: 4 };
+ }
+
+ if (getListLength(themeList) > 2000) {
+ return alerts.showConfirmationAlert({
+ content: "Your list is over than 2000 characters. Are you sure?",
+ confirmText: "Yes",
+ cancelText: "No",
+ onConfirm: async () => await sendList(ctx.channel.id, themeList),
+ });
+ }
+
+ await sendList(ctx.channel.id, themeList);
+ return { type: 4 };
+}
+
+async function handlePluginList(detailed: boolean, ctx: any) {
+ const alwaysDetailed = storage.pluginListAlwaysDetailed ?? false;
+ const pluginList = [
+ `**My Plugin List | ${Object.keys(plugins).length} Plugins**`,
+ "",
+ ];
+
+ for (const plugin of Object.values(plugins)) {
+ const { enabled, manifest, id } = plugin;
+ const { name, description, authors } = manifest;
+
+ if (detailed || alwaysDetailed) {
+ pluginList.push(
+ `> **Name**: ${name}`,
+ `> **Status**: ${enabled ? STATUS.ENABLED : STATUS.DISABLED}`,
+ `> **Description**: ${description}`,
+ `> **Authors**: ${addonAuthors(authors)}`,
+ `> **[Install!](${id})**`,
+ "",
+ );
+ } else {
+ pluginList.push(
+ `> ${enabled ? STATUS.ENABLED : STATUS.DISABLED} **${name}** by ${addonAuthors(authors)}`,
+ );
+ }
+ }
+
+ const isListTooLong = getListLength(pluginList) > maxMessageLength;
+
+ if (isListTooLong && !isSLMPluginInstalled()) {
+ const fixNonce = Date.now().toString();
+ Clyde.sendBotMessage(
+ ctx.channel.id,
+ `Your list is too long to send it! Please install the [Split Large Messages](${SPLIT_LARGE_MESSAGES_PLUGIN}) plugin.`,
+ void 0,
+ { nonce: fixNonce },
+ );
+ return { type: 4 };
+ } else if (isListTooLong && !isSLMPluginEnabled()) {
+ const fixNonce = Date.now().toString();
+ Clyde.sendBotMessage(
+ ctx.channel.id,
+ "Your list is too long to send it! You have the Split Large Messages plugin installed, but it's not enabled!\n> Please enable it in order to send the list.",
+ void 0,
+ { nonce: fixNonce },
+ );
+ return { type: 4 };
+ }
+
+ if (getListLength(pluginList) > 2000) {
+ return alerts.showConfirmationAlert({
+ content: "Your list is over than 2000 characters. Are you sure?",
+ confirmText: "Yes",
+ cancelText: "No",
+ onConfirm: async () => await sendList(ctx.channel.id, pluginList),
+ });
+ }
+
+ await sendList(ctx.channel.id, pluginList);
+ return { type: 4 };
+}
+
+// Register Commands
const registerCommands = () => {
// Cat Facts Command
commands.push(
@@ -182,8 +340,81 @@ const registerCommands = () => {
type: 1,
}),
);
+
+ // Plugin List Command
+ commands.push(
+ registerCommand({
+ name: "plugin-list",
+ displayName: "plugin list",
+ description: "Send your plugin list to the current channel",
+ displayDescription: "Send your plugin list to the current channel",
+ options: [
+ {
+ name: "detailed",
+ description: "Whether to send a list with detailed information.",
+ type: 5,
+ required: false,
+ displayName: "detailed",
+ displayDescription:
+ "Whether to send a list with detailed information.",
+ },
+ ],
+ execute: async (args, ctx) => {
+ const detailed =
+ args.find((arg) => arg.name === "detailed")?.value ?? false;
+ return handlePluginList(detailed, ctx);
+ },
+ applicationId: "-1",
+ inputType: 1,
+ type: 1,
+ }),
+ );
+
+ // Theme List Command
+ commands.push(
+ registerCommand({
+ name: "theme-list",
+ displayName: "theme list",
+ description: "Send your theme list to the current channel",
+ displayDescription: "Send your theme list to the current channel",
+ options: [
+ {
+ name: "detailed",
+ description: "Whether to send a list with detailed information.",
+ type: 5,
+ required: false,
+ displayName: "detailed",
+ displayDescription:
+ "Whether to send a list with detailed information.",
+ },
+ ],
+ execute: async (args, ctx) => {
+ const detailed =
+ args.find((arg) => arg.name === "detailed")?.value ?? false;
+ return handleThemeList(detailed, ctx);
+ },
+ applicationId: "-1",
+ inputType: 1,
+ type: 1,
+ }),
+ );
};
+// Initialize storage
+if (!storage.factSettings) {
+ storage.factSettings = {
+ sendAsReply: true,
+ includeCitation: false,
+ };
+}
+
+if (!storage.listSettings) {
+ storage.listSettings = {
+ pluginListAlwaysDetailed: false,
+ themeListAlwaysDetailed: false,
+ };
+}
+
export default {
onLoad: () => {
console.log("[All-In-One Commands] Plugin loaded!");
diff --git a/plugins/all-in-one/settings.tsx b/plugins/all-in-one/settings.tsx
index 48acc0e..3a84421 100644
--- a/plugins/all-in-one/settings.tsx
+++ b/plugins/all-in-one/settings.tsx
@@ -5,80 +5,85 @@ import { getAssetIDByName } from "@vendetta/ui/assets";
import { ErrorBoundary, Forms } from "@vendetta/ui/components";
const { FormSwitchRow, FormIcon, FormSection, FormDivider } = Forms;
+
const Icons = {
- List: getAssetIDByName('ic_list'),
- Copy: getAssetIDByName('ic_copy_message_link'),
- Settings: getAssetIDByName('ic_settings'),
- Fact: getAssetIDByName('ic_info')
+ List: getAssetIDByName("ic_list"),
+ Message: getAssetIDByName("ic_message"),
+ Copy: getAssetIDByName("ic_copy_message_link"),
+ Info: getAssetIDByName("ic_info"),
+ Theme: getAssetIDByName("ic_theme"),
+ Plugin: getAssetIDByName("ic_plugins"),
};
-// Initialize storage with default values if not set
-if (!storage.factSettings) {
- storage.factSettings = {
- sendAsReply: true,
- includeCitation: false
- };
-}
-
-if (!storage.listSettings) {
- storage.listSettings = {
- pluginListAlwaysDetailed: false,
- themeListAlwaysDetailed: false
- };
-}
-
export default () => {
- useProxy(storage);
+ useProxy(storage);
- return (
-
-
- {/* Plugin List Settings */}
-
- }
- onValueChange={(value: boolean) => {
- storage.listSettings.pluginListAlwaysDetailed = value;
- }}
- value={storage.listSettings.pluginListAlwaysDetailed}
- />
-
- }
- onValueChange={(value: boolean) => {
- storage.listSettings.themeListAlwaysDetailed = value;
- }}
- value={storage.listSettings.themeListAlwaysDetailed}
- />
-
+ if (!storage.factSettings) {
+ storage.factSettings = {
+ sendAsReply: true,
+ includeCitation: false,
+ };
+ }
- {/* Fact Command Settings */}
-
- }
- onValueChange={(value: boolean) => {
- storage.factSettings.sendAsReply = value;
- }}
- value={storage.factSettings.sendAsReply}
- />
-
- }
- onValueChange={(value: boolean) => {
- storage.factSettings.includeCitation = value;
- }}
- value={storage.factSettings.includeCitation}
- />
-
-
-
- );
+ if (!storage.listSettings) {
+ storage.listSettings = {
+ pluginListAlwaysDetailed: false,
+ themeListAlwaysDetailed: false,
+ };
+ }
+
+ return (
+
+
+ {/* Fact Commands Settings */}
+
+ }
+ onValueChange={(value: boolean) => {
+ storage.factSettings.sendAsReply = value;
+ }}
+ value={storage.factSettings.sendAsReply}
+ />
+
+ }
+ onValueChange={(value: boolean) => {
+ storage.factSettings.includeCitation = value;
+ }}
+ value={storage.factSettings.includeCitation}
+ />
+
+
+ {/* Plugin List Settings */}
+
+ }
+ onValueChange={(value: boolean) => {
+ storage.listSettings.pluginListAlwaysDetailed = value;
+ }}
+ value={storage.listSettings.pluginListAlwaysDetailed}
+ />
+
+
+ {/* Theme List Settings */}
+
+ }
+ onValueChange={(value: boolean) => {
+ storage.listSettings.themeListAlwaysDetailed = value;
+ }}
+ value={storage.listSettings.themeListAlwaysDetailed}
+ />
+
+
+
+ );
};