New Settings menu update

This commit is contained in:
Sqaaakoi 2024-08-23 15:53:51 +12:00
parent 4518705185
commit 317c386933
No known key found for this signature in database
3 changed files with 91 additions and 49 deletions

View file

@ -8,12 +8,14 @@ import { useSettings } from "@api/Settings";
import { classNameFactory } from "@api/Styles";
import { PluginCard } from "@components/PluginSettings";
import { ChangeList } from "@utils/ChangeList";
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { Alerts, Button, Flex, Forms, Parser, React, Text, Tooltip, useMemo } from "@webpack/common";
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, writeKnownPlugins } from "./knownPlugins";
import { getNewPlugins, getNewSettings, KnownPluginSettingsMap, writeKnownSettings } from "./knownSettings";
const cl = classNameFactory("vc-plugins-");
@ -21,29 +23,10 @@ let hasSeen = false;
// Most of this was stolen from PluginSettings directly.
export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalProps; newPlugins: Set<string>; }) {
export function NewPluginsModal({ modalProps, newPlugins, newSettings }: { modalProps: ModalProps; newPlugins: Set<string>; newSettings: KnownPluginSettingsMap; }) {
const settings = useSettings();
const changes = React.useMemo(() => new ChangeList<string>(), []);
React.useEffect(() => {
return () => void (changes.hasChanges && Alerts.show({
title: "Restart required",
body: (
<>
<p>The following plugins require a restart:</p>
<div>{changes.map((s, i) => (
<>
{i > 0 && ", "}
{Parser.parse("`" + s + "`")}
</>
))}</div>
</>
),
confirmText: "Restart now",
cancelText: "Later!",
onConfirm: () => location.reload()
}));
}, []);
let updateContinueButton = () => { };
const depMap = React.useMemo(() => {
const o = {} as Record<string, string[]>;
@ -59,8 +42,13 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP
return o;
}, []);
const sortedPlugins = useMemo(() => [...newPlugins].map(pn => Plugins[pn])
.sort((a, b) => a.name.localeCompare(b.name)), []);
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[];
@ -82,10 +70,14 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP
<PluginCard
onMouseLeave={onMouseLeave}
onMouseEnter={onMouseEnter}
onRestartNeeded={name => changes.handleChange(name)}
onRestartNeeded={name => {
changes.handleChange(name);
updateContinueButton();
}}
disabled={true}
plugin={p}
key={p.name}
isNew={newPlugins.has(p.name)}
/>
)}
</Tooltip>
@ -93,10 +85,14 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP
} else {
plugins.push(
<PluginCard
onRestartNeeded={name => changes.handleChange(name)}
onRestartNeeded={name => {
changes.handleChange(name);
updateContinueButton();
}}
disabled={false}
plugin={p}
key={p.name}
isNew={newPlugins.has(p.name)}
/>
);
}
@ -105,7 +101,16 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP
return <ModalRoot {...modalProps} size={ModalSize.MEDIUM} >
<ModalHeader>
<Text variant="heading-lg/semibold">New Plugins ({[...plugins, ...requiredPlugins].length})</Text>
<Text variant="heading-lg/semibold">New Plugins and Settings ({[...plugins, ...requiredPlugins].length})</Text>
<Tooltip text="Dismiss for this session">
{tooltipProps =>
<ModalCloseButton
{...tooltipProps}
onClick={modalProps.onClose}
className={cl("close")}
/>
}
</Tooltip>
</ModalHeader>
<ModalContent>
<div className={cl("grid")}>
@ -114,20 +119,46 @@ export function NewPluginsModal({ modalProps, newPlugins }: { modalProps: ModalP
</ModalContent>
<ModalFooter>
<Flex direction={Flex.Direction.HORIZONTAL_REVERSE}>
<Button
color={Button.Colors.GREEN}
onClick={async () => {
await writeKnownPlugins();
modalProps.onClose();
}}
>
Continue
</Button>
<ContinueButton
close={modalProps.onClose}
changes={changes}
callback={(v: () => void) => updateContinueButton = v}
/>
</Flex>
</ModalFooter>
</ModalRoot>;
}
function ContinueButton(props: { callback: (update: () => void) => void; changes: ChangeList<string>; close: () => any; }) {
const update = useForceUpdater();
props.callback(update);
return <Tooltip
text={<>
The following plugins require a restart:
<div>{props.changes.map((s, i) => (
<>
{i > 0 && ", "}
{Parser.parse("`" + s + "`")}
</>
))}</div>
</>}
shouldShow={props.changes.hasChanges}
>
{tooltipProps =>
<Button
{...tooltipProps}
color={Button.Colors.GREEN}
onClick={async () => {
await writeKnownSettings();
props.changes.hasChanges ? location.reload() : props.close();
}}
>
{props.changes.hasChanges ? "Restart" : "Continue"}
</Button>
}
</Tooltip>;
}
function makeDependencyList(deps: string[]) {
return (
@ -140,12 +171,14 @@ function makeDependencyList(deps: string[]) {
export async function openNewPluginsModal() {
const newPlugins = await getNewPlugins();
if (newPlugins.size && !hasSeen) {
const newSettings = await getNewSettings();
if (newSettings.size && !hasSeen) {
hasSeen = true;
openModal(modalProps => (
<NewPluginsModal
modalProps={modalProps}
newPlugins={newPlugins}
newSettings={newSettings}
/>
));
}

View file

@ -7,19 +7,22 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { KNOWN_PLUGINS_DATA_KEY } from "./knownPlugins";
import * as KnownSettings from "./knownSettings";
import { KNOWN_PLUGINS_LEGACY_DATA_KEY, KNOWN_SETTINGS_DATA_KEY } from "./knownSettings";
import { openNewPluginsModal } from "./NewPluginsModal";
export default definePlugin({
name: "NewPluginsManager",
description: "Utility that notifies you when new plugins are added to Vencord",
authors: [Devs.Sqaaakoi],
enabledByDefault: true,
enabledByDefault: true, // This is intentional.
flux: {
async POST_CONNECTION_OPEN() {
openNewPluginsModal();
}
},
openNewPluginsModal,
KNOWN_PLUGINS_DATA_KEY
KNOWN_PLUGINS_LEGACY_DATA_KEY,
KNOWN_SETTINGS_DATA_KEY,
KnownSettings
});

View file

@ -11,11 +11,6 @@ import plugins from "~plugins";
export type KnownPluginSettingsMap = Map<string, Set<string>>;
type PluginSettings = {
[setting: string]: any;
enabled?: boolean;
};
export const KNOWN_PLUGINS_LEGACY_DATA_KEY = "NewPluginsManager_KnownPlugins";
export const KNOWN_SETTINGS_DATA_KEY = "NewPluginsManager_KnownSettings";
@ -35,7 +30,7 @@ export async function getKnownSettings(): Promise<KnownPluginSettingsMap> {
let map = await DataStore.get(KNOWN_SETTINGS_DATA_KEY) as KnownPluginSettingsMap;
if (map === undefined) {
const knownPlugins = await DataStore.get(KNOWN_PLUGINS_LEGACY_DATA_KEY) ?? [] as string[];
DataStore.del(KNOWN_PLUGINS_LEGACY_DATA_KEY);
// DataStore.del(KNOWN_PLUGINS_LEGACY_DATA_KEY);
const Plugins = [...Object.keys(plugins), ...knownPlugins];
map = getCurrentSettings(Plugins);
DataStore.set(KNOWN_SETTINGS_DATA_KEY, map);
@ -48,7 +43,7 @@ export async function getNewSettings(): Promise<KnownPluginSettingsMap> {
const knownSettings = await getKnownSettings();
map.forEach((settings, plugin) => {
const filteredSettings = [...settings].filter(setting => !knownSettings.get(plugin)?.has(setting));
if (filteredSettings.length === 0 && knownSettings.has(plugin)) return map.delete(plugin);
if (!filteredSettings.length) return map.delete(plugin);
map.set(plugin, new Set(filteredSettings));
});
return map;
@ -77,3 +72,14 @@ export async function writeKnownSettings() {
});
await DataStore.set(KNOWN_SETTINGS_DATA_KEY, allSettings);
}
export async function debugWipeSomeData() {
const settings = await getKnownSettings();
settings.forEach((value, key) => {
if (Math.random() > 0.8) {
if (Math.random() > 0.5) return settings.set(key, new Set([...value].filter(() => Math.random() > 0.5)));
return settings.delete(key);
}
});
await DataStore.set(KNOWN_SETTINGS_DATA_KEY, settings);
}