diff --git a/src/api/Settings.ts b/src/api/Settings.ts index 7fb1193b0..64a71b8af 100644 --- a/src/api/Settings.ts +++ b/src/api/Settings.ts @@ -224,7 +224,7 @@ export function migratePluginSettings(name: string, ...oldNames: string[]) { } } -export function migrateSettingsToArrays(pluginName: string, settings: string[], stringSeparator: string = ",") { +export function migrateSettingsToArrays(pluginName: string, settings: string[], stringSeparator: string | ((input: string) => string[]) = ",") { const { plugins } = SettingsStore.plain; for (const setting of settings) { @@ -232,7 +232,8 @@ export function migrateSettingsToArrays(pluginName: string, settings: string[], logger.info(`Migrating setting ${setting} from ${pluginName} to list`); // @ts-ignore if (plugins[pluginName][setting] === "") plugins[pluginName][setting] = plugins[pluginName][setting].default ?? []; - else plugins[pluginName][setting] = plugins[pluginName][setting].split(stringSeparator); + else if (typeof stringSeparator === "string") plugins[pluginName][setting] = plugins[pluginName][setting].split(stringSeparator); + else plugins[pluginName][setting] = stringSeparator(plugins[pluginName][setting]); } } diff --git a/src/components/PluginSettings/components/SettingArrayComponent.tsx b/src/components/PluginSettings/components/SettingArrayComponent.tsx index d2ef77cab..d739914e2 100644 --- a/src/components/PluginSettings/components/SettingArrayComponent.tsx +++ b/src/components/PluginSettings/components/SettingArrayComponent.tsx @@ -6,13 +6,26 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; -import { debounce } from "@shared/debounce"; +import SearchModal from "@components/SearchModal"; import { Margins } from "@utils/margins"; -import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; +import { closeModal, openModal } from "@utils/modal"; import { wordsFromCamel, wordsToTitle } from "@utils/text"; import { OptionType, PluginOptionArray } from "@utils/types"; -import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack"; -import { Avatar, Button, ChannelStore, Flex, Forms, GuildStore, Heading, IconUtils, React, Text, TextInput, useCallback, useEffect, useRef, useState } from "@webpack/common"; +import { findByCodeLazy, findComponentByCodeLazy } from "@webpack"; +import { + Avatar, + Button, + ChannelStore, + Flex, + Forms, + GuildStore, + IconUtils, + React, + Text, + TextInput, + useEffect, + useState, +} from "@webpack/common"; import { Channel, Guild } from "discord-types/general"; import { ISettingElementProps } from "."; @@ -21,28 +34,30 @@ const cl = classNameFactory("vc-plugin-modal-"); // TODO add interfaces for the stuff from the modal instead of using any +// TODO also add types to all the vars :husk: :husk: const UserMentionComponent = findComponentByCodeLazy(".USER_MENTION)"); const getDMChannelIcon = findByCodeLazy(".getChannelIconURL({"); const GroupDMAvatars = findComponentByCodeLazy(".AvatarSizeSpecs[", "getAvatarURL"); -const SearchBarModule = findByPropsLazy("SearchBar", "Checkbox"); -const SearchBarWrapper = findByPropsLazy("SearchBar", "Item"); -const SearchHandler = findByCodeLazy("createSearchContext", "setLimit"); + const CloseIcon = () => { return - + ; }; const CheckMarkIcon = () => { return - + ; }; const SearchIcon = () => { - return + return ; @@ -88,112 +103,15 @@ export function SettingArrayComponent({ setItems(pluginSettings[id]); } - function SearchModal({ modalProps, close, val }: { modalProps: ModalProps; close(): void; val?: string; }) { - - const [searchText, setSearchText] = useState(val || ""); - const [searchState, setSearchState] = useState({ - results: [], - query: searchText - }); - // channels:0, guilds:1, users:2 - const [results, setResults] = useState>({ - "channels": [], - "guilds": [], - "users": [] - }); - const [selected, setSelected] = useState([]); - - const onConfirm = () => { - - }; - - const searchHandlerRef = useRef(null); - - useEffect(() => { - const handler = new SearchHandler((results, query) => { - setSearchState({ - results, - query - }); - }); - searchHandlerRef.current = handler; - - return () => { - handler.destroy(); - }; - }, []); - - const search = useCallback(debounce(() => { - if (searchHandlerRef.current) { - searchHandlerRef.current.search(searchText.trim()); - setResults({ - "channels": [...searchHandlerRef.current._groupDMResults, ...searchHandlerRef.current._textChannelResults, ...searchHandlerRef.current._voiceChannelResults], - "guilds": searchHandlerRef.current._guildResults, - "users": searchHandlerRef.current._userResults - }); - } - }, 300), [searchText]); - - useEffect(() => { - search(); - }, [searchText, search]); - - - return ( - - - - - Search for { - option.type === OptionType.USERS ? "Users" : option.type === OptionType.CHANNELS ? "Channels" : "Guilds" - } - All selected items will be added to {wordsToTitle(wordsFromCamel(id))} - - - - - - - - - - - - Confirm - - - Cancel - - - - - ); - } - function openSearchModal(val?: string) { const key = openModal(modalProps => ( closeModal(key)} - val={val} + input={val} + subText={"All selected items will be added to " + wordsToTitle(wordsFromCamel(id))} + searchType={option.type === OptionType.USERS ? "USERS" : option.type === OptionType.CHANNELS ? "CHANNELS" : "GUILDS"} + onSubmit={v => console.log(v)} /> )); } @@ -262,37 +180,36 @@ export function SettingArrayComponent({ switch (type) { case 2: return - - + + ; case 5: return - - + + ; case 13: return - - - + + + ; case 15: return - - + + ; default: // Text channel icon return - + ; } }; - // collapsible guild list with channels in it const channels: Record = {}; const dmChannels: Channel[] = []; const elements: React.JSX.Element[] = []; @@ -311,14 +228,14 @@ export function SettingArrayComponent({ channels[channel.guild_id].push(channel); } - const userMention = channel => { + const userMention = (channel: Channel) => { return ; }; - const gdmComponent = channel => { + const gdmComponent = (channel: Channel) => { return {channel.recipients.length >= 2 && channel.icon == null ? ( diff --git a/src/plugins/consoleJanitor/index.ts b/src/plugins/consoleJanitor/index.ts index d251ff740..7c6fef467 100644 --- a/src/plugins/consoleJanitor/index.ts +++ b/src/plugins/consoleJanitor/index.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { definePluginSettings } from "@api/Settings"; +import { definePluginSettings, migrateSettingsToArrays } from "@api/Settings"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType, StartAt } from "@utils/types"; @@ -24,6 +24,8 @@ const NoopLogger = { const logAllow = new Set(); +migrateSettingsToArrays("consoleJanitor", ["whitelistedLoggers"], s => s.split(";").map(x => x.trim())); + const settings = definePluginSettings({ disableLoggers: { type: OptionType.BOOLEAN, @@ -38,12 +40,12 @@ const settings = definePluginSettings({ restartNeeded: true }, whitelistedLoggers: { - type: OptionType.STRING, - description: "Semi colon separated list of loggers to allow even if others are hidden", - default: "GatewaySocket; Routing/Utils", - onChange(newVal: string) { + type: OptionType.ARRAY, + description: "List of loggers to allow even if others are hidden", + default: ["GatewaySocket", "Routing/Utils"], + onChange(newVal: string[]) { logAllow.clear(); - newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow)); + newVal.forEach(logAllow.add.bind(logAllow)); } } }); @@ -57,7 +59,7 @@ export default definePlugin({ startAt: StartAt.Init, start() { logAllow.clear(); - this.settings.store.whitelistedLoggers?.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow)); + this.settings.store.whitelistedLoggers.forEach(logAllow.add.bind(logAllow)); }, NoopLogger: () => NoopLogger, diff --git a/src/plugins/invisibleChat.desktop/index.tsx b/src/plugins/invisibleChat.desktop/index.tsx index e8a8c65d9..e799ad4f2 100644 --- a/src/plugins/invisibleChat.desktop/index.tsx +++ b/src/plugins/invisibleChat.desktop/index.tsx @@ -93,7 +93,7 @@ const ChatBarIcon: ChatBarButton = ({ isMainChat }) => { }; -migrateSettingsToArrays("InvisibleChat", ["savedPasswords"]); +migrateSettingsToArrays("InvisibleChat", ["savedPasswords"], s => s.split(",").map(s => s.trim())); const settings = definePluginSettings({ savedPasswords: { @@ -209,7 +209,7 @@ export function isCorrectPassword(result: string): boolean { } export async function iteratePasswords(message: Message): Promise { - const passwords = settings.store.savedPasswords.map(s => s.trim()); + const passwords = settings.store.savedPasswords; if (!message?.content || !passwords?.length) return false; diff --git a/src/utils/types.ts b/src/utils/types.ts index 679085818..8b35e7321 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -279,6 +279,8 @@ export interface PluginSettingArrayDef { popoutText?: string; hidePopout?: boolean; default?: any[]; + + onChange?(newValue: any[]): void; } export interface IPluginOptionComponentProps {