1
0
Fork 1
mirror of https://github.com/Vendicated/Vencord.git synced 2025-01-10 09:56:24 +00:00

make searching from modal work

This commit is contained in:
Elvy 2025-01-05 02:25:04 +01:00
parent f82cb5188b
commit 7c729de800

View file

@ -7,13 +7,14 @@
import { classNameFactory } from "@api/Styles"; import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary"; import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex"; import { Flex } from "@components/Flex";
import { debounce } from "@shared/debounce";
import { Margins } from "@utils/margins"; import { Margins } from "@utils/margins";
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { wordsFromCamel, wordsToTitle } from "@utils/text"; import { wordsFromCamel, wordsToTitle } from "@utils/text";
import { OptionType, PluginOptionList } from "@utils/types"; import { OptionType, PluginOptionList } from "@utils/types";
import { findByCodeLazy, findComponentByCodeLazy } from "@webpack"; import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { Avatar, Button, ChannelStore, Forms, GuildStore, IconUtils, React, Text, TextInput, useEffect, useState } from "@webpack/common"; import { Avatar, Button, ChannelStore, Forms, GuildStore, IconUtils, React, Text, TextInput, useCallback, useEffect, useRef, useState } from "@webpack/common";
import { Channel, Guild } from "discord-types/general"; import { Channel, Guild } from "discord-types/general";
import { JSX } from "react";
import { ISettingElementProps } from "."; import { ISettingElementProps } from ".";
@ -22,9 +23,9 @@ const cl = classNameFactory("vc-plugin-modal-");
const UserMentionComponent = findComponentByCodeLazy(".USER_MENTION)"); const UserMentionComponent = findComponentByCodeLazy(".USER_MENTION)");
const getDMChannelIcon = findByCodeLazy(".getChannelIconURL({"); const getDMChannelIcon = findByCodeLazy(".getChannelIconURL({");
const GroupDMAvatars = findComponentByCodeLazy(".AvatarSizeSpecs[", "getAvatarURL"); const GroupDMAvatars = findComponentByCodeLazy(".AvatarSizeSpecs[", "getAvatarURL");
const SearchBarModule = findByPropsLazy("SearchBar", "Checkbox");
const SearchBar = findComponentByCodeLazy("focus(){let{current:"); const SearchBarWrapper = findByPropsLazy("SearchBar", "Item");
const SearchHandler = findByCodeLazy("createSearchContext", "setLimit");
const CloseIcon = () => { const CloseIcon = () => {
return <svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" width="18" height="18"> return <svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" width="18" height="18">
@ -65,6 +66,89 @@ export function SettingArrayComponent({
setItems(pluginSettings[id]); setItems(pluginSettings[id]);
} }
function SearchModal({ modalProps, close, val }: { modalProps: ModalProps; close(): void; val?: string; }) {
const [searchText, setSearchText] = useState<string>(val || "");
const [searchState, setSearchState] = useState({
results: [],
query: searchText
});
// channels:0, guilds:1, users:2
const [results, setResults] = useState<Record<string, any[]>>({
"channels": [],
"guilds": [],
"users": []
});
const searchHandlerRef = useRef<typeof SearchHandler | null>(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 (
<ModalRoot {...modalProps} size={ModalSize.MEDIUM}>
<ModalHeader>
<Text variant="heading-lg/semibold" style={{ flexGrow: 1 }}>Search for {
option.type === OptionType.USERS ? "Users" : option.type === OptionType.CHANNELS ? "Channels" : "Guilds"
}</Text>
<ModalCloseButton onClick={close} />
</ModalHeader>
<ModalContent>
<SearchBarWrapper.SearchBar
size={SearchBarModule.SearchBar.Sizes.MEDIUM}
placeholder={"Search for a" + (option.type === OptionType.USERS ? " user" : option.type === OptionType.CHANNELS ? " channel" : " guild")}
query={searchText}
onChange={setSearchText}
autofocus={true}
/>
</ModalContent>
<ModalFooter>
</ModalFooter>
</ModalRoot>
);
}
function openSearchModal(val?: string) {
const key = openModal(modalProps => (
<SearchModal
modalProps={modalProps}
close={() => closeModal(key)}
val={val}
/>
));
}
const removeButton = (index: number) => { const removeButton = (index: number) => {
return ( return (
<Button <Button
@ -162,7 +246,7 @@ export function SettingArrayComponent({
// collapsible guild list with channels in it // collapsible guild list with channels in it
const channels: Record<string, Channel[]> = {}; const channels: Record<string, Channel[]> = {};
const dmChannels: Channel[] = []; const dmChannels: Channel[] = [];
const elements: JSX.Element[] = []; const elements: React.JSX.Element[] = [];
for (const item of items) { for (const item of items) {
const channel = ChannelStore.getChannel(item); const channel = ChannelStore.getChannel(item);
if (!channel) { if (!channel) {
@ -259,7 +343,7 @@ export function SettingArrayComponent({
return; return;
} }
if (option.type !== OptionType.ARRAY && !(text.length >= 18 && text.length <= 19 && !isNaN(Number(text)))) { if (option.type !== OptionType.ARRAY && !(text.length >= 18 && text.length <= 19 && !isNaN(Number(text)))) {
// openSearchModal(); openSearchModal();
setText(""); setText("");
// FIXME // FIXME
return; return;
@ -330,9 +414,7 @@ export function SettingArrayComponent({
<Button <Button
id={cl("search-button")} id={cl("search-button")}
size={Button.Sizes.MIN} size={Button.Sizes.MIN}
onClick={() => { onClick={openSearchModal}
// openSearchModal();
}}
style={ style={
{ background: "none" } { background: "none" }
} }