/* * Vencord, a Discord client mod * Copyright (c) 2024 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import { useSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; import { PluginCard } from "@components/PluginSettings"; import { ChangeList } from "@utils/ChangeList"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { useForceUpdater } from "@utils/react"; import { Button, Flex, Forms, Parser, React, Text, Tooltip, useMemo } from "@webpack/common"; import { JSX } from "react"; import Plugins from "~plugins"; import { getNewPlugins, getNewSettings, KnownPluginSettingsMap, writeKnownSettings } from "./knownSettings"; const cl = classNameFactory("vc-plugins-"); let hasSeen = false; // Most of this was stolen from PluginSettings directly. export function NewPluginsModal({ modalProps, newPlugins, newSettings }: { modalProps: ModalProps; newPlugins: Set; newSettings: KnownPluginSettingsMap; }) { const settings = useSettings(); const changes = React.useMemo(() => new ChangeList(), []); let updateContinueButton = () => { }; const depMap = React.useMemo(() => { const o = {} as Record; for (const plugin in Plugins) { const deps = Plugins[plugin].dependencies; if (deps) { for (const dep of deps) { o[dep] ??= []; o[dep].push(plugin); } } } return o; }, []); const mapPlugins = (array: string[]) => array.map(pn => Plugins[pn]) .sort((a, b) => a.name.localeCompare(b.name)); const sortedPlugins = useMemo(() => [ ...mapPlugins([...newPlugins]), ...mapPlugins([...newSettings.keys()].filter(p => !newPlugins.has(p))) ], []); const plugins = [] as JSX.Element[]; const requiredPlugins = [] as JSX.Element[]; for (const p of sortedPlugins) { if (p.hidden) continue; const isRequired = p.required || depMap[p.name]?.some(d => settings.plugins[d].enabled); if (isRequired) { const tooltipText = p.required ? "This plugin is required for Vencord to function." : makeDependencyList(depMap[p.name]?.filter(d => settings.plugins[d].enabled)); requiredPlugins.push( {({ onMouseLeave, onMouseEnter }) => ( { changes.handleChange(name); updateContinueButton(); }} disabled={true} plugin={p} key={p.name} isNew={newPlugins.has(p.name)} /> )} ); } else { plugins.push( { changes.handleChange(name); updateContinueButton(); }} disabled={false} plugin={p} key={p.name} isNew={newPlugins.has(p.name)} /> ); } } return New Plugins and Settings ({[...plugins, ...requiredPlugins].length}) {tooltipProps => }
{[...plugins, ...requiredPlugins]}
void) => updateContinueButton = v} />
; } function ContinueButton(props: { callback: (update: () => void) => void; changes: ChangeList; close: () => any; }) { const update = useForceUpdater(); props.callback(update); return The following plugins require a restart:
{props.changes.map((s, i) => ( <> {i > 0 && ", "} {Parser.parse("`" + s + "`")} ))}
} shouldShow={props.changes.hasChanges} > {tooltipProps => }
; } function makeDependencyList(deps: string[]) { return ( This plugin is required by: {deps.map((dep: string) => {dep})} ); } export async function openNewPluginsModal() { const newPlugins = await getNewPlugins(); const newSettings = await getNewSettings(); if (newSettings.size && !hasSeen) { hasSeen = true; openModal(modalProps => ( )); } }