diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx
index 2825022b7..b8d01276a 100644
--- a/src/components/PluginSettings/PluginModal.tsx
+++ b/src/components/PluginSettings/PluginModal.tsx
@@ -40,11 +40,11 @@ import {
ISettingElementProps,
SettingBooleanComponent,
SettingCustomComponent,
+ SettingListComponent,
SettingNumericComponent,
SettingSelectComponent,
SettingSliderComponent,
SettingTextComponent,
- SettingListComponent,
} from "./components";
import { openContributorModal } from "./ContributorModal";
import { GithubButton, WebsiteButton } from "./LinkIconButton";
@@ -83,10 +83,10 @@ const Components: Record.
*/
+import ErrorBoundary from "@components/ErrorBoundary";
+import { Flex } from "@components/Flex";
import { Margins } from "@utils/margins";
import { wordsFromCamel, wordsToTitle } from "@utils/text";
-import { PluginOptionSelect } from "@utils/types";
-import { Forms, useState, useEffect, ChannelStore, UserStore, GuildStore } from "@webpack/common";
+import { OptionType, PluginOptionList } from "@utils/types";
+import { findComponentByCodeLazy } from "@webpack";
+import { Button,ChannelStore, Forms, GuildStore, React, useState } from "@webpack/common";
import { ISettingElementProps } from ".";
+import { Channel } from "discord-types/general";
-export function SettingListComponent({ option, pluginSettings, definedSettings, onChange, onError, id }: ISettingElementProps) {
+const UserMentionComponent = findComponentByCodeLazy(".USER_MENTION)");
+
+const CloseIcon = () => {
+ return ;
+};
+
+interface UserMentionComponentProps {
+ id: string;
+ channelId: string;
+ guildId: string;
+}
+
+export function SettingListComponent({
+ option,
+ pluginSettings,
+ definedSettings,
+ onChange,
+ onError,
+ id
+}: ISettingElementProps) {
const [error, setError] = useState(null);
const [items, setItems] = useState([]);
@@ -34,31 +59,75 @@ export function SettingListComponent({ option, pluginSettings, definedSettings,
setItems([...items, newItem]);
setNewItem("");
}
+ pluginSettings[id] = items;
};
+ if (items.length === 0 && pluginSettings[id].length !== 0) {
+ setItems(pluginSettings[id]);
+ }
+
const removeItem = (index: number) => {
setItems(items.filter((_, i) => i !== index));
+ pluginSettings[id] = items;
};
- useEffect(() => {
- onError(error !== null);
- }, [error]);
-
function handleChange(newValue) {
- const isValid = option.isValid?.call(definedSettings, newValue) ?? true;
- if (typeof isValid === "string") setError(isValid);
- else if (!isValid) setError("Invalid input provided.");
- else {
- setError(null);
- onChange(newValue);
- }
+ onChange(newValue);
}
+ function wrapChannel(id: string) {
+ const channel = ChannelStore.getChannel(id) as Channel;
+ if (!channel) {
+ return "Unknown Channel";
+ }
+ return (GuildStore.getGuild(channel.guild_id)?.name ?? "Unknown Guild") + " - " + channel.name;
+ }
+
+ // FIXME make channels and guilds nicer!
return (
{wordsToTitle(wordsFromCamel(id))}
{option.description}
+
+ {items.map((item, index) => (
+
+
+ {option.type === OptionType.USERS ? (
+
+ ) : option.type === OptionType.CHANNELS ? (
+ {wrapChannel(item)}
+ ) : option.type === OptionType.GUILDS ? (
+
+ {GuildStore.getGuild(item)?.name || "Unknown Guild"}
+
+ // TODO add logo to guild and channel?
+ ) : (
+ {item}
+ )}
+
+
+
+ ))}
+
+
+
{error && {error}}
diff --git a/src/plugins/_api/settingLists.tsx b/src/plugins/_api/settingLists.tsx
index 0af3558c9..fbf616adc 100644
--- a/src/plugins/_api/settingLists.tsx
+++ b/src/plugins/_api/settingLists.tsx
@@ -8,7 +8,7 @@ import { NavContextMenuPatchCallback } from "@api/ContextMenu";
import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
-import { Menu, useState } from "@webpack/common";
+import { Menu, React } from "@webpack/common";
function createContextMenu(name: "Guild" | "User" | "Channel", value: any) {
return (
@@ -26,16 +26,24 @@ function renderRegisteredPlugins(name: "Guild" | "User" | "Channel", value: any)
const type = name === "Guild" ? OptionType.GUILDS : name === "User" ? OptionType.USERS : OptionType.CHANNELS;
const plugins = registeredPlugins[type];
- const [checkedItems, setCheckedItems] = useState>({});
+
+ const [checkedItems, setCheckedItems] = React.useState>(
+ Object.fromEntries(
+ Object.keys(plugins).flatMap(plugin =>
+ plugins[plugin].map(setting => [`${plugin}-${setting}-${value.id}`, Vencord.Plugins.plugins[plugin].settings?.store[setting].includes(value.id)])
+ )
+ )
+ );
const handleCheckboxClick = (plugin: string, setting: string) => {
- const key = `${plugin}-${setting}`;
+ const key = `${plugin}-${setting}-${value.id}`;
setCheckedItems(prevState => ({
...prevState,
[key]: !prevState[key]
}));
- // @ts-ignore (can't be undefined because settings have to exist for this to be called in the first place)
+ // @ts-ignore settings must be defined otherwise we wouldn't be here
const s = Vencord.Plugins.plugins[plugin].settings.store[setting];
+ // @ts-ignore
Vencord.Plugins.plugins[plugin].settings.store[setting] = s.includes(value.id)
? s.filter(id => id !== value.id)
: [...s, value.id];
@@ -49,10 +57,9 @@ function renderRegisteredPlugins(name: "Guild" | "User" | "Channel", value: any)
{plugins[plugin].map(setting => (
handleCheckboxClick(plugin, setting)}
- checked={checkedItems[`${plugin}-${setting}`]}
+ checked={checkedItems[`${plugin}-${setting}-${value.id}`]}
/>
))}
@@ -93,7 +100,7 @@ const registeredPlugins: Record = O extends PluginSettingStri
O extends PluginSettingSelectDef ? O["options"][number]["value"] :
O extends PluginSettingSliderDef ? number :
O extends PluginSettingComponentDef ? any :
+ O extends PluginSettingListDef ? any[] :
never;
type PluginSettingDefaultType = O extends PluginSettingSelectDef ? (
O["options"] extends { default?: boolean; }[] ? O["options"][number]["value"] : undefined
@@ -361,6 +363,7 @@ export type PluginOptionBoolean = PluginSettingBooleanDef & PluginSettingCommon
export type PluginOptionSelect = PluginSettingSelectDef & PluginSettingCommon & IsDisabled & IsValid;
export type PluginOptionSlider = PluginSettingSliderDef & PluginSettingCommon & IsDisabled & IsValid;
export type PluginOptionComponent = PluginSettingComponentDef & PluginSettingCommon;
+export type PluginOptionList = PluginSettingListDef & PluginSettingCommon;
export type PluginNative any>> = {
[key in keyof PluginExports]: