feat: @vc-requiredPlugins
This commit is contained in:
parent
b7cdb96e09
commit
b6547b463b
|
@ -255,3 +255,21 @@ export function DeleteIcon(props: IconProps) {
|
||||||
</Icon>
|
</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 { Settings, useSettings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { CogWheel, DeleteIcon } from "@components/Icons";
|
import { CogWheel, DeleteIcon, PluginIcon } from "@components/Icons";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
import { AddonCard } from "@components/VencordSettings/AddonCard";
|
import { AddonCard } from "@components/VencordSettings/AddonCard";
|
||||||
import { SettingsTab, wrapTab } from "@components/VencordSettings/shared";
|
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 { getThemeInfo, stripBOM, type UserThemeHeader } from "@utils/themes/bd";
|
||||||
import { usercssParse } from "@utils/themes/usercss";
|
import { usercssParse } from "@utils/themes/usercss";
|
||||||
import { findByCodeLazy, findByPropsLazy, findLazy } from "@webpack";
|
import { findByCodeLazy, findByPropsLazy, findLazy } from "@webpack";
|
||||||
import { Button, Card, FluxDispatcher, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common";
|
import { Button, Card, FluxDispatcher, Forms, React, showToast, TabBar, TextArea, Tooltip, useEffect, useMemo, useRef, useState } from "@webpack/common";
|
||||||
import type { ComponentType, Ref, SyntheticEvent } from "react";
|
import { type ComponentType, type Ref, type SyntheticEvent } from "react";
|
||||||
import type { UserstyleHeader } from "usercss-meta";
|
import type { UserstyleHeader } from "usercss-meta";
|
||||||
|
|
||||||
|
import { isPluginEnabled } from "../../plugins";
|
||||||
import { UserCSSSettingsModal } from "./UserCSSModal";
|
import { UserCSSSettingsModal } from "./UserCSSModal";
|
||||||
|
|
||||||
type FileInput = ComponentType<{
|
type FileInput = ComponentType<{
|
||||||
|
@ -118,6 +119,9 @@ interface UserCSSCardProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function UserCSSThemeCard({ theme, enabled, onChange, onDelete }: UserCSSCardProps) {
|
function UserCSSThemeCard({ theme, enabled, onChange, onDelete }: UserCSSCardProps) {
|
||||||
|
const missingPlugins = useMemo(() =>
|
||||||
|
theme.requiredPlugins?.filter(p => !isPluginEnabled(p)), [theme]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AddonCard
|
<AddonCard
|
||||||
name={theme.name ?? "Unknown"}
|
name={theme.name ?? "Unknown"}
|
||||||
|
@ -127,6 +131,19 @@ function UserCSSThemeCard({ theme, enabled, onChange, onDelete }: UserCSSCardPro
|
||||||
setEnabled={onChange}
|
setEnabled={onChange}
|
||||||
infoButton={
|
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 && (
|
{theme.vars && (
|
||||||
<div style={{ cursor: "pointer" }} onClick={
|
<div style={{ cursor: "pointer" }} onClick={
|
||||||
() => openModal(modalProps =>
|
() => openModal(modalProps =>
|
||||||
|
|
|
@ -10,16 +10,22 @@ import { parse as originalParse, UserstyleHeader } from "usercss-meta";
|
||||||
const UserCSSLogger = new Logger("UserCSS", "#d2acf5");
|
const UserCSSLogger = new Logger("UserCSS", "#d2acf5");
|
||||||
|
|
||||||
export async function usercssParse(text: string, fileName: string): Promise<UserstyleHeader> {
|
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) {
|
if (errors.length) {
|
||||||
UserCSSLogger.warn("Parsed", fileName, "with errors:", errors);
|
UserCSSLogger.warn("Parsed", fileName, "with errors:", errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const requiredPlugins = metadata["vc-requiredPlugins"]?.split(",").map(p => p.trim());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...metadata,
|
...metadata,
|
||||||
fileName,
|
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;
|
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.
|
* The name of your style.
|
||||||
*
|
*
|
||||||
|
@ -107,7 +115,20 @@ declare module "usercss-meta" {
|
||||||
* A list of variables the style defines.
|
* A list of variables the style defines.
|
||||||
*/
|
*/
|
||||||
vars: Record<string, UserCSSVariable>;
|
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