From 7c3a5bf31ccc2f05947521ac4f40003cd675e9a5 Mon Sep 17 00:00:00 2001
From: kmmiio99o <164557248+kmmiio99o@users.noreply.github.com>
Date: Sat, 27 Sep 2025 20:10:37 +0200
Subject: [PATCH] Refactor settings UI and improve long list handling
- Rewrite settings page using TableRowGroup and TableSwitchRow - Add
commands overview and about sections to settings - Replace deprecated
Forms components with updated UI components - Add dialogs for
installing/enabling Split Large Messages plugin - Improve alerts for
sending long plugin/theme lists
---
plugins/all-in-one/settings.tsx | 180 +++++++++++++++--------
plugins/all-in-one/src/commands/lists.ts | 63 ++++++--
2 files changed, 170 insertions(+), 73 deletions(-)
diff --git a/plugins/all-in-one/settings.tsx b/plugins/all-in-one/settings.tsx
index 3a84421..9b498b2 100644
--- a/plugins/all-in-one/settings.tsx
+++ b/plugins/all-in-one/settings.tsx
@@ -1,89 +1,153 @@
-import { ReactNative } from "@vendetta/metro/common";
-import { storage } from "@vendetta/plugin";
-import { useProxy } from "@vendetta/storage";
+import { plugin } from "@vendetta";
import { getAssetIDByName } from "@vendetta/ui/assets";
-import { ErrorBoundary, Forms } from "@vendetta/ui/components";
+import { React } from "@vendetta/metro/common";
+import { findByProps } from "@vendetta/metro";
-const { FormSwitchRow, FormIcon, FormSection, FormDivider } = Forms;
+const { ScrollView } = findByProps("ScrollView");
+const { TableRowGroup, TableSwitchRow, Stack } = findByProps(
+ "TableSwitchRow",
+ "TableRowGroup",
+ "Stack",
+);
-const Icons = {
- 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"),
-};
+const get = (k: string, fallback: any = "") => plugin.storage[k] ?? fallback;
+const set = (k: string, v: any) => (plugin.storage[k] = v);
-export default () => {
- useProxy(storage);
-
- if (!storage.factSettings) {
- storage.factSettings = {
- sendAsReply: true,
- includeCitation: false,
- };
- }
-
- if (!storage.listSettings) {
- storage.listSettings = {
- pluginListAlwaysDetailed: false,
- themeListAlwaysDetailed: false,
- };
- }
+export default function Settings() {
+ const [_, forceUpdate] = React.useReducer((x) => ~x, 0);
+ const update = () => forceUpdate();
return (
-
-
- {/* Fact Commands Settings */}
-
-
+
+ {/* Facts Commands Settings */}
+
+ }
+ icon={getAssetIDByName("ic_reply_24px")}
+ value={get("factSettings.sendAsReply", true)}
onValueChange={(value: boolean) => {
- storage.factSettings.sendAsReply = value;
+ set("factSettings", {
+ ...get("factSettings", {}),
+ sendAsReply: value,
+ });
+ update();
}}
- value={storage.factSettings.sendAsReply}
/>
-
- }
+ icon={getAssetIDByName("ic_info")}
+ value={get("factSettings.includeCitation", false)}
onValueChange={(value: boolean) => {
- storage.factSettings.includeCitation = value;
+ set("factSettings", {
+ ...get("factSettings", {}),
+ includeCitation: value,
+ });
+ update();
}}
- value={storage.factSettings.includeCitation}
/>
-
+
{/* Plugin List Settings */}
-
-
+ }
+ icon={getAssetIDByName("ic_message_copy")}
+ value={get("listSettings.pluginListAlwaysDetailed", false)}
onValueChange={(value: boolean) => {
- storage.listSettings.pluginListAlwaysDetailed = value;
+ set("listSettings", {
+ ...get("listSettings", {}),
+ pluginListAlwaysDetailed: value,
+ });
+ update();
}}
- value={storage.listSettings.pluginListAlwaysDetailed}
/>
-
+
{/* Theme List Settings */}
-
-
+ }
+ icon={getAssetIDByName("ic_theme")}
+ value={get("listSettings.themeListAlwaysDetailed", false)}
onValueChange={(value: boolean) => {
- storage.listSettings.themeListAlwaysDetailed = value;
+ set("listSettings", {
+ ...get("listSettings", {}),
+ themeListAlwaysDetailed: value,
+ });
+ update();
}}
- value={storage.listSettings.themeListAlwaysDetailed}
/>
-
-
-
+
+
+ {/* Commands Overview */}
+
+
+
+
+
+
+
+
+
+
+ {/* About Section */}
+
+
+
+
+
);
-};
+}
diff --git a/plugins/all-in-one/src/commands/lists.ts b/plugins/all-in-one/src/commands/lists.ts
index 7e1eaec..5115c31 100644
--- a/plugins/all-in-one/src/commands/lists.ts
+++ b/plugins/all-in-one/src/commands/lists.ts
@@ -3,7 +3,8 @@ import { themes } from "@vendetta/themes";
import { plugins } from "@vendetta/plugins";
import { storage } from "@vendetta/plugin";
import { alerts } from "@vendetta/ui";
-import { showAlert } from "../utils/messages";
+import { sendMessage } from "../utils/messages";
+import { openURL } from "@vendetta/metro/common";
const SPLIT_LARGE_MESSAGES_PLUGIN =
"https://vd-plugins.github.io/proxy/actuallythesun.github.io/vendetta-plugins/SplitLargeMessages/";
@@ -30,6 +31,40 @@ const isSLMPluginEnabled = () =>
Object.values(plugins).find((p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN)
?.enabled ?? false;
+const showSplitPluginDialog = () => {
+ return alerts.showConfirmationAlert({
+ title: "Large Message Warning",
+ content:
+ "This list is too long to send! Would you like to install the Split Large Messages plugin?",
+ confirmText: "Install Plugin",
+ cancelText: "Cancel",
+ confirmColor: "brand",
+ onConfirm: () => {
+ openURL(SPLIT_LARGE_MESSAGES_PLUGIN);
+ },
+ });
+};
+
+const showEnablePluginDialog = () => {
+ return alerts.showConfirmationAlert({
+ title: "Plugin Disabled",
+ content:
+ "The Split Large Messages plugin is installed but disabled. Would you like to enable it now?",
+ confirmText: "Enable Plugin",
+ cancelText: "Cancel",
+ confirmColor: "brand",
+ onConfirm: () => {
+ // Enable the plugin
+ const slmPlugin = Object.values(plugins).find(
+ (p) => p.id === SPLIT_LARGE_MESSAGES_PLUGIN,
+ );
+ if (slmPlugin) {
+ slmPlugin.enabled = true;
+ }
+ },
+ });
+};
+
// Command handlers
async function handlePluginList(detailed: boolean, ctx: any) {
const alwaysDetailed =
@@ -61,18 +96,17 @@ async function handlePluginList(detailed: boolean, ctx: any) {
if (getListLength(pluginList) > 2000) {
if (!isSLMPluginInstalled()) {
- showAlert("List too long! Install Split Large Messages plugin");
- return { type: 4 };
+ return showSplitPluginDialog();
}
if (!isSLMPluginEnabled()) {
- showAlert("Enable Split Large Messages plugin to send long lists!");
- return { type: 4 };
+ return showEnablePluginDialog();
}
return alerts.showConfirmationAlert({
- content: "Your list is over 2000 characters. Send anyway?",
- confirmText: "Yes",
- cancelText: "No",
+ title: "Large Message",
+ content: "This list is over 2000 characters. Send anyway?",
+ confirmText: "Send",
+ cancelText: "Cancel",
onConfirm: () => sendMessage(ctx.channel.id, formatList(pluginList)),
});
}
@@ -114,18 +148,17 @@ async function handleThemeList(detailed: boolean, ctx: any) {
if (getListLength(themeList) > 2000) {
if (!isSLMPluginInstalled()) {
- showAlert("List too long! Install Split Large Messages plugin");
- return { type: 4 };
+ return showSplitPluginDialog();
}
if (!isSLMPluginEnabled()) {
- showAlert("Enable Split Large Messages plugin to send long lists!");
- return { type: 4 };
+ return showEnablePluginDialog();
}
return alerts.showConfirmationAlert({
- content: "Your list is over 2000 characters. Send anyway?",
- confirmText: "Yes",
- cancelText: "No",
+ title: "Large Message",
+ content: "This list is over 2000 characters. Send anyway?",
+ confirmText: "Send",
+ cancelText: "Cancel",
onConfirm: () => sendMessage(ctx.channel.id, formatList(themeList)),
});
}