From c6cae1cb823bf1056b14592ae33c058b2a8d7c2a Mon Sep 17 00:00:00 2001 From: fox3000foxy Date: Wed, 19 Feb 2025 23:44:40 +0100 Subject: [PATCH] Added customVoiceFilter plugin --- .../customVoiceFilter/ConfirmModal.tsx | 51 +++ .../CreateVoiceFilterModal.tsx | 111 ++++++ src/plugins/customVoiceFilter/ErrorModal.tsx | 47 +++ src/plugins/customVoiceFilter/HelpModal.tsx | 57 +++ src/plugins/customVoiceFilter/Icons.tsx | 76 ++++ .../customVoiceFilter/VoiceFiltersModal.tsx | 169 ++++++++ .../customVoiceFilter/WikiHomeModal.tsx | 99 +++++ src/plugins/customVoiceFilter/index.tsx | 364 ++++++++++++++++++ src/plugins/customVoiceFilter/native.ts | 89 +++++ src/plugins/customVoiceFilter/utils.ts | 93 +++++ 10 files changed, 1156 insertions(+) create mode 100644 src/plugins/customVoiceFilter/ConfirmModal.tsx create mode 100644 src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx create mode 100644 src/plugins/customVoiceFilter/ErrorModal.tsx create mode 100644 src/plugins/customVoiceFilter/HelpModal.tsx create mode 100644 src/plugins/customVoiceFilter/Icons.tsx create mode 100644 src/plugins/customVoiceFilter/VoiceFiltersModal.tsx create mode 100644 src/plugins/customVoiceFilter/WikiHomeModal.tsx create mode 100644 src/plugins/customVoiceFilter/index.tsx create mode 100644 src/plugins/customVoiceFilter/native.ts create mode 100644 src/plugins/customVoiceFilter/utils.ts diff --git a/src/plugins/customVoiceFilter/ConfirmModal.tsx b/src/plugins/customVoiceFilter/ConfirmModal.tsx new file mode 100644 index 000000000..d95ef411e --- /dev/null +++ b/src/plugins/customVoiceFilter/ConfirmModal.tsx @@ -0,0 +1,51 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; +import { Button, Flex, Forms, Text } from "@webpack/common"; +import { JSX } from "react"; + +// Open Confirm Modal +export function openConfirmModal(message: string, accept: (key: string) => void): string { + const key = openModal(modalProps => ( + accept(key)} + close={() => closeModal(key)} + /> + )); + return key; +} + +interface ConfirmModalProps { + modalProps: ModalProps; + message: string; + accept: () => void; + close: () => void; +} + +function ConfirmModal({ modalProps, message, accept, close }: ConfirmModalProps): JSX.Element { + return ( + + + + Confirm + + + + + {message} + + + + + + + + + ); +} diff --git a/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx b/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx new file mode 100644 index 000000000..9a98f083d --- /dev/null +++ b/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx @@ -0,0 +1,111 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; +import { Button, Flex, Forms, Select, TextInput, useCallback, useMemo, UserStore, useState } from "@webpack/common"; +import { SelectOption } from "@webpack/types"; +import { JSX } from "react"; + +import { voices } from "."; +import { openErrorModal } from "./ErrorModal"; +import { IVoiceFilter, useVoiceFiltersStore } from "./index"; +const requiredFields = ["name", "iconURL", "onnxFileUrl", "previewSoundURLs"] as const satisfies readonly (keyof IVoiceFilter)[]; + + +export function openCreateVoiceModal(defaultValue?: Partial): string { + const key = openModal(modalProps => ( + closeModal(key)} defaultValue={defaultValue} /> + )); + return key; +} + +interface CreateVoiceFilterModalProps { + modalProps: ModalProps; + close: () => void; + defaultValue?: Partial; +} + + +// Create Voice Filter Modal +function CreateVoiceFilterModal({ modalProps, close, defaultValue }: CreateVoiceFilterModalProps): JSX.Element { + const currentUser = useMemo(() => UserStore.getCurrentUser(), []); + const [voiceFilter, setVoiceFilter] = useState(() => ( + { author: currentUser.id, name: "", iconURL: "", styleKey: "", onnxFileUrl: "", ...defaultValue } + )); + + const update = useCallback((value: IVoiceFilter[K], key: K) => { + setVoiceFilter(prev => ({ ...prev, [key]: value })); + }, []); + const submit = useCallback(() => { + if (requiredFields.every(field => voiceFilter[field])) { + useVoiceFiltersStore.getState().downloadVoicepack(JSON.stringify({ + id: voiceFilter.author + "-" + voiceFilter.name.toLowerCase().replace(/ /g, "-"), + available: true, + temporarilyAvailable: false, + custom: true, + splashGradient: "radial-gradient(circle, #d9a5a2 0%, rgba(0,0,0,0) 100%)", + baseColor: "#d9a5a2", + ...voiceFilter + } satisfies IVoiceFilter)); + close(); + } else { + openErrorModal("Please fill in all required fields"); + } + }, [voiceFilter]); + + const keyOptions: SelectOption[] = useMemo(() => + [{ value: "", label: "(empty)" }, ...Object.keys(voices).map(name => ({ value: name, label: name }))], + []); + + return ( + + + + {voiceFilter.id ? "Edit a voice filter" : "Create a voice filter"} + + + + + + + Name* + + + + Icon URL* + + + + Style Key +