feat: @vc-requiredPlugins
This commit is contained in:
parent
b7cdb96e09
commit
b6547b463b
4 changed files with 68 additions and 6 deletions
|
@ -255,3 +255,21 @@ export function DeleteIcon(props: IconProps) {
|
|||
</Icon>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A plugin icon, created by CorellanStoma. https://github.com/CreArts-Community/Settings-Icons
|
||||
*/
|
||||
export function PluginIcon(props: IconProps) {
|
||||
return (
|
||||
<Icon
|
||||
{...props}
|
||||
className={classes(props.className, "vc-plugin-icon")}
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7s2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"
|
||||
/>
|
||||
</Icon>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import "./themesStyles.css";
|
|||
import { Settings, useSettings } from "@api/Settings";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import { Flex } from "@components/Flex";
|
||||
import { CogWheel, DeleteIcon } from "@components/Icons";
|
||||
import { CogWheel, DeleteIcon, PluginIcon } from "@components/Icons";
|
||||
import { Link } from "@components/Link";
|
||||
import { AddonCard } from "@components/VencordSettings/AddonCard";
|
||||
import { SettingsTab, wrapTab } from "@components/VencordSettings/shared";
|
||||
|
@ -34,10 +34,11 @@ import type { ThemeHeader } from "@utils/themes";
|
|||
import { getThemeInfo, stripBOM, type UserThemeHeader } from "@utils/themes/bd";
|
||||
import { usercssParse } from "@utils/themes/usercss";
|
||||
import { findByCodeLazy, findByPropsLazy, findLazy } from "@webpack";
|
||||
import { Button, Card, FluxDispatcher, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
|
||||
import type { ComponentType, Ref, SyntheticEvent } from "react";
|
||||
import { Button, Card, FluxDispatcher, Forms, React, showToast, TabBar, TextArea, Tooltip, useEffect, useMemo, useRef, useState } from "@webpack/common";
|
||||
import { type ComponentType, type Ref, type SyntheticEvent } from "react";
|
||||
import type { UserstyleHeader } from "usercss-meta";
|
||||
|
||||
import { isPluginEnabled } from "../../plugins";
|
||||
import { UserCSSSettingsModal } from "./UserCSSModal";
|
||||
|
||||
type FileInput = ComponentType<{
|
||||
|
@ -118,6 +119,9 @@ interface UserCSSCardProps {
|
|||
}
|
||||
|
||||
function UserCSSThemeCard({ theme, enabled, onChange, onDelete }: UserCSSCardProps) {
|
||||
const missingPlugins = useMemo(() =>
|
||||
theme.requiredPlugins?.filter(p => !isPluginEnabled(p)), [theme]);
|
||||
|
||||
return (
|
||||
<AddonCard
|
||||
name={theme.name ?? "Unknown"}
|
||||
|
@ -127,6 +131,19 @@ function UserCSSThemeCard({ theme, enabled, onChange, onDelete }: UserCSSCardPro
|
|||
setEnabled={onChange}
|
||||
infoButton={
|
||||
<>
|
||||
{missingPlugins && missingPlugins.length > 0 && (
|
||||
<Tooltip text={"The following plugins are required, but aren't enabled: " + missingPlugins.join(", ")}>
|
||||
{({ onMouseLeave, onMouseEnter }) => (
|
||||
<div
|
||||
style={{ color: "var(--status-warning" }}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
<PluginIcon />
|
||||
</div>
|
||||
)}
|
||||
</Tooltip>
|
||||
)}
|
||||
{theme.vars && (
|
||||
<div style={{ cursor: "pointer" }} onClick={
|
||||
() => openModal(modalProps =>
|
||||
|
|
|
@ -10,16 +10,22 @@ import { parse as originalParse, UserstyleHeader } from "usercss-meta";
|
|||
const UserCSSLogger = new Logger("UserCSS", "#d2acf5");
|
||||
|
||||
export async function usercssParse(text: string, fileName: string): Promise<UserstyleHeader> {
|
||||
var { metadata, errors } = originalParse(text.replace(/\r/g, ""), { allowErrors: true });
|
||||
const { metadata, errors } = originalParse(text.replace(/\r/g, ""), {
|
||||
allowErrors: true,
|
||||
unknownKey: "assign"
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
UserCSSLogger.warn("Parsed", fileName, "with errors:", errors);
|
||||
}
|
||||
|
||||
const requiredPlugins = metadata["vc-requiredPlugins"]?.split(",").map(p => p.trim());
|
||||
|
||||
return {
|
||||
...metadata,
|
||||
fileName,
|
||||
id: await getUserCssId(metadata)
|
||||
id: await getUserCssId(metadata),
|
||||
requiredPlugins
|
||||
};
|
||||
}
|
||||
|
||||
|
|
23
src/utils/themes/usercss/usercss-meta.d.ts
vendored
23
src/utils/themes/usercss/usercss-meta.d.ts
vendored
|
@ -55,6 +55,14 @@ declare module "usercss-meta" {
|
|||
*/
|
||||
fileName: string;
|
||||
|
||||
/**
|
||||
* The required plugins for this style.
|
||||
*
|
||||
* @vencord Specific to Vencord, not part of the original module.
|
||||
* @see {@link vc-requiredPlugins}
|
||||
*/
|
||||
requiredPlugins?: string[];
|
||||
|
||||
/**
|
||||
* The name of your style.
|
||||
*
|
||||
|
@ -107,7 +115,20 @@ declare module "usercss-meta" {
|
|||
* A list of variables the style defines.
|
||||
*/
|
||||
vars: Record<string, UserCSSVariable>;
|
||||
|
||||
/**
|
||||
* Required plugins for this style to work. Comma-separated list of plugin names.
|
||||
*
|
||||
* @vencord This is a Vencord-specific extension, however we wish for this to become a standard for client mods
|
||||
* to implement, hence the more generic namespaced name.
|
||||
*/
|
||||
"vc-requiredPlugins"?: string;
|
||||
}
|
||||
|
||||
export function parse(text: string, options: { allowErrors: boolean; }): { metadata: UserstyleHeader; errors: { code: string; args: any; }[]; };
|
||||
type UserCSSParseOptions = {
|
||||
allowErrors: boolean;
|
||||
unknownKey: "assign";
|
||||
};
|
||||
|
||||
export function parse(text: string, options: UserCSSParseOptions): { metadata: UserstyleHeader; errors: { code: string; args: any; }[]; };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue