diff --git a/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx b/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx index 220d2dd47..a75a81c2f 100644 --- a/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx +++ b/src/plugins/customVoiceFilter/CreateVoiceFilterModal.tsx @@ -1,111 +1,113 @@ -/* - * 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)" }, ...(voices ? 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 - update(value, "styleKey")} + isSelected={v => v === voiceFilter.styleKey} + serialize={String} + /> + + + ONNX File URL* + + + + Preview Sound URL* + update(value ? [value] : undefined, "previewSoundURLs")} style={{ width: "100%" }} value={voiceFilter.previewSoundURLs?.[0] ?? ""} required /> + + + + + + + + + + + + ); +} diff --git a/src/plugins/customVoiceFilter/SettingsModal.tsx b/src/plugins/customVoiceFilter/SettingsModal.tsx index 0820e188f..e35f070d7 100644 --- a/src/plugins/customVoiceFilter/SettingsModal.tsx +++ b/src/plugins/customVoiceFilter/SettingsModal.tsx @@ -1,78 +1,93 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { Margins } from "@utils/margins"; -import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { Button, Flex, Forms, Slider } from "@webpack/common"; -import { JSX } from "react"; - -import plugin, { settings } from "./index"; - - -export function openSettingsModal(): string { - const key = openModal(modalProps => ( - closeModal(key)} /> - )); - return key; -} - -interface SettingsModalProps { - modalProps: ModalProps; - close: () => void; -} - - -// Create Voice Filter Modal -function SettingsModal({ modalProps, close }: SettingsModalProps): JSX.Element { - const settingsState = settings.use(); - const { settings: { def } } = plugin; - - return ( - - - - Settings - - - - - - - Pitch - {def.pitch.description} - settingsState.pitch = value} - onValueRender={value => `${value}`} - stickToMarkers={true} - /> - - - Frequency - {def.frequency.description} - settingsState.frequency = value} - onValueRender={value => `${value}Hz`} - stickToMarkers={true} - /> - - - - - - - - - - ); -} +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { Margins } from "@utils/margins"; +import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; +import { PluginNative } from "@utils/types"; +import { Button, Flex, Forms, Slider } from "@webpack/common"; +import { JSX } from "react"; + +import plugin, { settings, useVoiceFiltersStore } from "./index"; + +const Native = VencordNative.pluginHelpers.CustomVoiceFilters as PluginNative; +export function openSettingsModal(): string { + const key = openModal(modalProps => ( + closeModal(key)} /> + )); + return key; +} + +interface SettingsModalProps { + modalProps: ModalProps; + close: () => void; +} + +function openModelFolder() { + const { modulePath } = useVoiceFiltersStore.getState(); + Native.openFolder(modulePath); +} + +// Create Voice Filter Modal +function SettingsModal({ modalProps, close }: SettingsModalProps): JSX.Element { + const settingsState = settings.use(); + const { settings: { def } } = plugin; + const { deleteAll, exportVoiceFilters, importVoiceFilters } = useVoiceFiltersStore(); + return ( + + + + Settings + + + + + + + Pitch + {def.pitch.description} + settingsState.pitch = value} + onValueRender={value => `${value}`} + stickToMarkers={true} + /> + + + Frequency + {def.frequency.description} + settingsState.frequency = value} + onValueRender={value => `${value}Hz`} + stickToMarkers={true} + /> + + + Voicepacks: + Here you can manage your voicepacks. + + + + + + + + + + + + + + + + ); +} diff --git a/src/plugins/customVoiceFilter/VoiceFiltersModal.tsx b/src/plugins/customVoiceFilter/VoiceFiltersModal.tsx index bd0696ec1..4f10a33a8 100644 --- a/src/plugins/customVoiceFilter/VoiceFiltersModal.tsx +++ b/src/plugins/customVoiceFilter/VoiceFiltersModal.tsx @@ -11,7 +11,6 @@ import { Button, Flex, Forms, Text, TextInput, Tooltip, useEffect, useState } fr import { JSX } from "react"; import { openCreateVoiceModal } from "./CreateVoiceFilterModal"; -import { openHelpModal } from "./HelpModal"; import { DownloadIcon, DownloadingIcon, PauseIcon, PlayIcon, RefreshIcon, TrashIcon } from "./Icons"; import { downloadCustomVoiceModel, getClient, IVoiceFilter, useVoiceFiltersStore, VoiceFilterStyles } from "./index"; import { openSettingsModal } from "./SettingsModal"; @@ -20,11 +19,6 @@ import { openWikiHomeModal } from "./WikiHomeModal"; const Native = VencordNative.pluginHelpers.CustomVoiceFilters as PluginNative; -function openModelFolder() { - const { modulePath } = useVoiceFiltersStore.getState(); - const modelFolder = Native.openFolder(modulePath); -} - export function openVoiceFiltersModal(): string { const key = openModal(modalProps => ( @@ -64,20 +58,15 @@ function VoiceFiltersModal({ modalProps, close, accept }: VoiceFiltersModalProps Download a voicepack from a url or paste a voicepack data here: - { if (e.key === "Enter") downloadVoicepack(url); }} - style={{ width: "100%" }} - /> - - - - - - - + + { if (e.key === "Enter") downloadVoicepack(url); }} + style={{ width: "100%" }} + /> + Voice filters list: @@ -94,7 +83,6 @@ function VoiceFiltersModal({ modalProps, close, accept }: VoiceFiltersModalProps -