From ef71a602089a91b8108d7be06db51ab90804d7e6 Mon Sep 17 00:00:00 2001 From: Vynx Date: Sat, 1 Aug 2026 22:34:43 -0500 Subject: [PATCH] Add CustomRPC presets (#1288) * Add CustomRPC presets * Update RpcSettings.tsx --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com> --- src/plugins/customRPC/RpcSettings.tsx | 119 +++++++++++++++++++++++--- src/plugins/customRPC/index.tsx | 16 ++-- src/plugins/customRPC/settings.css | 19 +++- 3 files changed, 136 insertions(+), 18 deletions(-) diff --git a/src/plugins/customRPC/RpcSettings.tsx b/src/plugins/customRPC/RpcSettings.tsx index f642e09be..d93b18278 100644 --- a/src/plugins/customRPC/RpcSettings.tsx +++ b/src/plugins/customRPC/RpcSettings.tsx @@ -6,21 +6,29 @@ import "./settings.css"; +import { DataStore } from "@api/index"; import { isPluginEnabled } from "@api/PluginManager"; import { Divider } from "@components/Divider"; import { Heading } from "@components/Heading"; import { resolveError } from "@components/settings/tabs/plugins/components/Common"; import { debounce } from "@shared/debounce"; import { classNameFactory } from "@utils/css"; +import { useAwaiter } from "@utils/react"; import { ActivityType } from "@vencord/discord-types/enums"; -import { Select, Text, TextInput, useState } from "@webpack/common"; +import { Button, Select, showToast, Text, TextInput, Toasts, useState } from "@webpack/common"; -import CustomRPCPlugin, { setRpc, settings, TimestampMode } from "."; +import CustomRPCPlugin, { RpcConfig, setRpc, settings, TimestampMode } from "."; const cl = classNameFactory("vc-customRPC-settings-"); +const PRESETS_KEY = "CustomRPC_presets"; type SettingsKey = keyof typeof settings.store; +interface RpcPreset { + name: string; + config: RpcConfig; +} + interface TextOption { settingsKey: SettingsKey; label: string; @@ -151,11 +159,90 @@ function SelectSetting({ settingsKey, label, options, disabled }: SelectOptio ); } -export function RPCSettings() { - const s = settings.use(); +function getCurrentConfig(): RpcConfig { + const { config, ...rpcConfig } = settings.store; + return rpcConfig; +} + +function PresetSettings({ onLoad }: { onLoad(): void; }) { + const [storedPresets] = useAwaiter(async () => await DataStore.get(PRESETS_KEY) ?? [], { fallbackValue: [] }); + const [changedPresets, setChangedPresets] = useState(null); + const [presetName, setPresetName] = useState(""); + const [selectedPreset, setSelectedPreset] = useState(""); + const presets = changedPresets ?? storedPresets; + + async function savePreset() { + const name = presetName.trim(); + if (!name) return; + + const nextPresets = [ + ...presets.filter(preset => preset.name !== name), + { name, config: getCurrentConfig() } + ].sort((a, b) => a.name.localeCompare(b.name)); + + await DataStore.set(PRESETS_KEY, nextPresets); + setChangedPresets(nextPresets); + setSelectedPreset(name); + showToast(`Saved preset ${name}.`, Toasts.Type.SUCCESS); + } + + function loadPreset() { + const preset = presets.find(preset => preset.name === selectedPreset); + if (!preset) return; + + Object.assign(settings.store, preset.config); + onLoad(); + updateRPC(); + showToast(`Loaded preset ${preset.name}.`, Toasts.Type.SUCCESS); + } + + async function deletePreset() { + const nextPresets = presets.filter(preset => preset.name !== selectedPreset); + if (nextPresets.length === presets.length) return; + + await DataStore.set(PRESETS_KEY, nextPresets); + setChangedPresets(nextPresets); + setSelectedPreset(""); + showToast(`Deleted preset ${selectedPreset}.`, Toasts.Type.SUCCESS); + } return ( -
+
+ Presets +
+ + +
+ {presets.length ? ( +
+