updated DiscordColorways to v5.6.4.2
This commit is contained in:
parent
101e25329e
commit
cba15d56d3
16 changed files with 665 additions and 1274 deletions
|
@ -19,146 +19,25 @@ import {
|
||||||
useState,
|
useState,
|
||||||
} from "@webpack/common";
|
} from "@webpack/common";
|
||||||
|
|
||||||
|
import { mainColors } from "../constants";
|
||||||
import { colorVariables } from "../css";
|
import { colorVariables } from "../css";
|
||||||
|
import { getHex } from "../utils";
|
||||||
interface ToolboxItem {
|
|
||||||
title: string;
|
|
||||||
onClick: () => void;
|
|
||||||
id?: string;
|
|
||||||
iconClassName?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ColorVarItems: ToolboxItem[] = colorVariables.map((colorVariable: string) => {
|
|
||||||
return {
|
|
||||||
title: "Copy " + colorVariable,
|
|
||||||
onClick: () => {
|
|
||||||
function getHex(str: string): string { return Object.assign(document.createElement("canvas").getContext("2d") as {}, { fillStyle: str }).fillStyle; }
|
|
||||||
Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue("--" + colorVariable)));
|
|
||||||
Toasts.show({ message: "Color " + colorVariable + " copied to clipboard", id: "toolbox-color-var-copied", type: 1 });
|
|
||||||
},
|
|
||||||
id: colorVariable
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const ToolboxItems: ToolboxItem[] = [
|
|
||||||
{
|
|
||||||
title: "Copy Accent Color",
|
|
||||||
onClick: () => {
|
|
||||||
function getHex(str: string): string {
|
|
||||||
return Object.assign(
|
|
||||||
document.createElement("canvas").getContext("2d") as {},
|
|
||||||
{ fillStyle: str }
|
|
||||||
).fillStyle;
|
|
||||||
}
|
|
||||||
Clipboard.copy(
|
|
||||||
getHex(
|
|
||||||
getComputedStyle(document.body).getPropertyValue(
|
|
||||||
"--brand-experiment"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Toasts.show({
|
|
||||||
message: "Accent color copied to clipboard",
|
|
||||||
id: "toolbox-accent-color-copied",
|
|
||||||
type: 1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
id: "colorways-toolbox_copy-accent",
|
|
||||||
iconClassName: "copy",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Copy Primary Color",
|
|
||||||
onClick: () => {
|
|
||||||
function getHex(str: string): string {
|
|
||||||
return Object.assign(
|
|
||||||
document.createElement("canvas").getContext("2d") as {},
|
|
||||||
{ fillStyle: str }
|
|
||||||
).fillStyle;
|
|
||||||
}
|
|
||||||
Clipboard.copy(
|
|
||||||
getHex(
|
|
||||||
getComputedStyle(document.body).getPropertyValue(
|
|
||||||
"--background-primary"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Toasts.show({
|
|
||||||
message: "Primary color copied to clipboard",
|
|
||||||
id: "toolbox-primary-color-copied",
|
|
||||||
type: 1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
id: "colorways-toolbox_copy-primary",
|
|
||||||
iconClassName: "copy",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Copy Secondary Color",
|
|
||||||
onClick: () => {
|
|
||||||
function getHex(str: string): string {
|
|
||||||
return Object.assign(
|
|
||||||
document.createElement("canvas").getContext("2d") as {},
|
|
||||||
{ fillStyle: str }
|
|
||||||
).fillStyle;
|
|
||||||
}
|
|
||||||
Clipboard.copy(
|
|
||||||
getHex(
|
|
||||||
getComputedStyle(document.body).getPropertyValue(
|
|
||||||
"--background-secondary"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Toasts.show({
|
|
||||||
message: "Secondary color copied to clipboard",
|
|
||||||
id: "toolbox-secondary-color-copied",
|
|
||||||
type: 1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
id: "colorways-toolbox_copy-secondary",
|
|
||||||
iconClassName: "copy",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Copy Tertiary Color",
|
|
||||||
onClick: () => {
|
|
||||||
function getHex(str: string): string {
|
|
||||||
return Object.assign(
|
|
||||||
document.createElement("canvas").getContext("2d") as {},
|
|
||||||
{ fillStyle: str }
|
|
||||||
).fillStyle;
|
|
||||||
}
|
|
||||||
Clipboard.copy(
|
|
||||||
getHex(
|
|
||||||
getComputedStyle(document.body).getPropertyValue(
|
|
||||||
"--background-tertiary"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Toasts.show({
|
|
||||||
message: "Tertiary color copied to clipboard",
|
|
||||||
id: "toolbox-tertiary-color-copied",
|
|
||||||
type: 1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
id: "colorways-toolbox_copy-tertiary",
|
|
||||||
iconClassName: "copy",
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function ({ modalProps }: { modalProps: ModalProps; }) {
|
export default function ({ modalProps }: { modalProps: ModalProps; }) {
|
||||||
const [colorVarItems, setColorVarItems] = useState<ToolboxItem[]>(ColorVarItems);
|
const [ColorVars, setColorVars] = useState<string[]>(colorVariables);
|
||||||
const [collapsedSettings, setCollapsedSettings] = useState<boolean>(true);
|
const [collapsedSettings, setCollapsedSettings] = useState<boolean>(true);
|
||||||
let results: ToolboxItem[];
|
let results: string[];
|
||||||
function searchToolboxItems(e: string) {
|
function searchToolboxItems(e: string) {
|
||||||
results = [];
|
results = [];
|
||||||
ColorVarItems.find((ToolboxItem: ToolboxItem) => {
|
colorVariables.find((colorVariable: string) => {
|
||||||
if (ToolboxItem.title.toLowerCase().includes(e.toLowerCase())) {
|
if (colorVariable.toLowerCase().includes(e.toLowerCase())) {
|
||||||
results.push(ToolboxItem);
|
results.push(colorVariable);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setColorVarItems(results);
|
setColorVars(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <ModalRoot {...modalProps} className="colorwayColorpicker">
|
||||||
<ModalRoot {...modalProps} className="colorwayColorpicker">
|
|
||||||
<Flex style={{ gap: "8px", marginBottom: "8px" }}>
|
<Flex style={{ gap: "8px", marginBottom: "8px" }}>
|
||||||
<TextInput
|
<TextInput
|
||||||
className="colorwaysColorpicker-search"
|
className="colorwaysColorpicker-search"
|
||||||
|
@ -175,7 +54,8 @@ export default function ({ modalProps }: { modalProps: ModalProps; }) {
|
||||||
<Button
|
<Button
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.TRANSPARENT}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => setCollapsedSettings(!collapsedSettings)}
|
onClick={() => setCollapsedSettings(!collapsedSettings)}
|
||||||
>
|
>
|
||||||
<svg width="32" height="24" viewBox="0 0 24 24" aria-hidden="true" role="img">
|
<svg width="32" height="24" viewBox="0 0 24 24" aria-hidden="true" role="img">
|
||||||
|
@ -184,37 +64,28 @@ export default function ({ modalProps }: { modalProps: ModalProps; }) {
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<ScrollerThin style={{ color: "var(--text-normal)" }} orientation="vertical" className={collapsedSettings ? " colorwaysColorpicker-collapsed" : ""} paddingFix>
|
<ScrollerThin style={{ color: "var(--text-normal)" }} orientation="vertical" className={collapsedSettings ? " colorwaysColorpicker-collapsed" : ""} paddingFix>
|
||||||
{colorVarItems.map((toolboxItem: ToolboxItem) => {
|
{ColorVars.map((colorVariable: string) => <div
|
||||||
return (
|
id={`colorways-colorstealer-item_${colorVariable}`}
|
||||||
<div
|
|
||||||
id={
|
|
||||||
"colorways-colorstealer-item_" +
|
|
||||||
toolboxItem.id
|
|
||||||
}
|
|
||||||
className="colorwaysCreator-settingItm colorwaysCreator-toolboxItm"
|
className="colorwaysCreator-settingItm colorwaysCreator-toolboxItm"
|
||||||
onClick={toolboxItem.onClick}
|
onClick={() => {
|
||||||
style={
|
Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue("--" + colorVariable)));
|
||||||
{
|
Toasts.show({ message: "Color " + colorVariable + " copied to clipboard", id: "toolbox-color-var-copied", type: 1 });
|
||||||
"--brand-experiment":
|
}} style={{ "--brand-experiment": `var(--${colorVariable})` } as React.CSSProperties}>
|
||||||
"var(--" + toolboxItem.id + ")",
|
{`Copy ${colorVariable}`}
|
||||||
} as React.CSSProperties
|
</div>)}
|
||||||
}
|
|
||||||
>
|
|
||||||
{toolboxItem.title}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ScrollerThin>
|
</ScrollerThin>
|
||||||
<Flex style={{ justifyContent: "space-between", marginTop: "8px" }} wrap="wrap" className={collapsedSettings ? "" : " colorwaysColorpicker-collapsed"}>
|
<Flex style={{ justifyContent: "space-between", marginTop: "8px" }} wrap="wrap" className={collapsedSettings ? "" : " colorwaysColorpicker-collapsed"}>
|
||||||
{ToolboxItems.map((toolboxItem: ToolboxItem, i: number) => <div
|
{mainColors.map(mainColor => <div
|
||||||
id={toolboxItem.id || `colorways-toolbox_item-${i}`}
|
id={`colorways-toolbox_copy-${mainColor.name}`}
|
||||||
className="colorwayToolbox-listItem"
|
className="colorwayToolbox-listItem"
|
||||||
>
|
>
|
||||||
<CopyIcon onClick={toolboxItem.onClick} width={20} height={20} className="colorwayToolbox-listItemSVG" />
|
<CopyIcon onClick={() => {
|
||||||
<span className="colorwaysToolbox-label">{toolboxItem.title}</span>
|
Clipboard.copy(getHex(getComputedStyle(document.body).getPropertyValue(mainColor.var)));
|
||||||
|
Toasts.show({ message: `${mainColor.title} color copied to clipboard`, id: `toolbox-${mainColor.name}-color-copied`, type: 1 });
|
||||||
|
}} width={20} height={20} className="colorwayToolbox-listItemSVG" />
|
||||||
|
<span className="colorwaysToolbox-label">{`Copy ${mainColor.title} Color`}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</ModalRoot>
|
</ModalRoot>;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
import * as DataStore from "@api/DataStore";
|
import * as DataStore from "@api/DataStore";
|
||||||
import { openModal } from "@utils/modal";
|
import { openModal } from "@utils/modal";
|
||||||
import { FluxDispatcher, Text, Tooltip, useCallback, useEffect, useState } from "@webpack/common";
|
import { FluxDispatcher, Text, Tooltip, useEffect, useState } from "@webpack/common";
|
||||||
import { FluxEvents } from "@webpack/types";
|
import { FluxEvents } from "@webpack/types";
|
||||||
|
|
||||||
import { PalleteIcon } from "./Icons";
|
import { PalleteIcon } from "./Icons";
|
||||||
import SelectorModal from "./SelectorModal";
|
import Selector from "./Selector";
|
||||||
|
|
||||||
export default function ({
|
export default function ({
|
||||||
listItemClass = "ColorwaySelectorBtnContainer",
|
listItemClass = "ColorwaySelectorBtnContainer",
|
||||||
|
@ -34,10 +34,8 @@ export default function ({
|
||||||
setIsThin(useThinMenuButton);
|
setIsThin(useThinMenuButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
const cached_setButtonVisibility = useCallback(setButtonVisibility, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
cached_setButtonVisibility();
|
setButtonVisibility();
|
||||||
});
|
});
|
||||||
|
|
||||||
FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, ({ isTall }) => {
|
FluxDispatcher.subscribe("COLORWAYS_UPDATE_BUTTON_HEIGHT" as FluxEvents, ({ isTall }) => {
|
||||||
|
@ -48,18 +46,13 @@ export default function ({
|
||||||
setVisibility(isVisible);
|
setVisibility(isVisible);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isThin) {
|
return <Tooltip text={
|
||||||
return (<Tooltip text={<>
|
!isThin ? <><span>Colorways</span><Text variant="text-xs/normal" style={{ color: "var(--text-muted)", fontWeight: 500 }}>{"Active Colorway: " + activeColorway}</Text></> : <span>{"Active Colorway: " + activeColorway}</span>
|
||||||
<span>Colorways</span>
|
} position="right" tooltipContentClassName="colorwaysBtn-tooltipContent"
|
||||||
<Text variant="text-xs/normal" style={{ color: "var(--text-muted)", fontWeight: 500 }}>{"Active Colorway: " + activeColorway}</Text>
|
|
||||||
</>} position="right" tooltipContentClassName={listItemTooltipClass}
|
|
||||||
>
|
>
|
||||||
{({ onMouseEnter, onMouseLeave, onClick }) => {
|
{({ onMouseEnter, onMouseLeave, onClick }) => visibility ? <div className="ColorwaySelectorBtnContainer">
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{visibility && <div className={listItemClass}>
|
|
||||||
<div
|
<div
|
||||||
className={listItemWrapperClass + " ColorwaySelectorBtn"}
|
className={"ColorwaySelectorBtn" + (isThin ? " ColorwaySelectorBtn_thin" : "")}
|
||||||
onMouseEnter={async () => {
|
onMouseEnter={async () => {
|
||||||
onMouseEnter();
|
onMouseEnter();
|
||||||
setActiveColorway(await DataStore.get("actveColorwayID") || "None");
|
setActiveColorway(await DataStore.get("actveColorwayID") || "None");
|
||||||
|
@ -67,42 +60,9 @@ export default function ({
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onClick();
|
onClick();
|
||||||
openModal(props => <SelectorModal modalProps={props} />);
|
openModal((props: any) => <Selector modalProps={props} />);
|
||||||
}}
|
}}
|
||||||
><PalleteIcon /></div>
|
>{isThin ? <Text variant="text-xs/normal" style={{ color: "var(--header-primary)", fontWeight: 700, fontSize: 9 }}>Colorways</Text> : <PalleteIcon />}</div>
|
||||||
</div>}
|
</div> : <></>}
|
||||||
</>
|
</Tooltip>;
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (<Tooltip text={<>
|
|
||||||
<span>Colorways</span>
|
|
||||||
<Text variant="text-xs/normal" style={{ color: "var(--text-muted)", fontWeight: 500 }}>{"Active Colorway: " + activeColorway}</Text>
|
|
||||||
</>} position="right" tooltipContentClassName={listItemTooltipClass}
|
|
||||||
>
|
|
||||||
{({ onMouseEnter, onMouseLeave, onClick }) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{visibility && <div className={listItemClass}>
|
|
||||||
<div
|
|
||||||
className={listItemWrapperClass + " ColorwaySelectorBtn ColorwaySelectorBtn_thin"}
|
|
||||||
onMouseEnter={async () => {
|
|
||||||
onMouseEnter();
|
|
||||||
setActiveColorway(await DataStore.get("actveColorwayID") || "None");
|
|
||||||
}}
|
|
||||||
onMouseLeave={onMouseLeave}
|
|
||||||
onClick={() => {
|
|
||||||
onClick();
|
|
||||||
openModal(props => <SelectorModal modalProps={props} />);
|
|
||||||
}}
|
|
||||||
><Text variant="text-xs/normal" style={{ color: "var(--header-primary)", fontWeight: 700, fontSize: 9 }}>Colorways</Text></div>
|
|
||||||
</div>}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { generateCss, getPreset } from "../css";
|
||||||
import { Colorway } from "../types";
|
import { Colorway } from "../types";
|
||||||
import { colorToHex, getHex, hexToString } from "../utils";
|
import { colorToHex, getHex, hexToString } from "../utils";
|
||||||
import ConflictingColorsModal from "./ConflictingColorsModal";
|
import ConflictingColorsModal from "./ConflictingColorsModal";
|
||||||
|
import InputColorwayIdModal from "./InputColorwayIdModal";
|
||||||
import ThemePreviewCategory from "./ThemePreview";
|
import ThemePreviewCategory from "./ThemePreview";
|
||||||
export default function ({
|
export default function ({
|
||||||
modalProps,
|
modalProps,
|
||||||
|
@ -51,26 +52,46 @@ export default function ({
|
||||||
const [collapsedSettings, setCollapsedSettings] = useState<boolean>(true);
|
const [collapsedSettings, setCollapsedSettings] = useState<boolean>(true);
|
||||||
const [collapsedPresets, setCollapsedPresets] = useState<boolean>(true);
|
const [collapsedPresets, setCollapsedPresets] = useState<boolean>(true);
|
||||||
const [preset, setPreset] = useState<string>("default");
|
const [preset, setPreset] = useState<string>("default");
|
||||||
const [presetColorArray, setPresetColorArray] = useState<string[]>(["accent", "primary", "secondary", "tertiary"]);
|
const [presetColorArray, setPresetColorArray] = useState<string[]>(["primary", "secondary", "tertiary", "accent"]);
|
||||||
|
|
||||||
|
const colorProps = {
|
||||||
|
accent: {
|
||||||
|
get: accentColor,
|
||||||
|
set: setAccentColor,
|
||||||
|
name: "Accent"
|
||||||
|
},
|
||||||
|
primary: {
|
||||||
|
get: primaryColor,
|
||||||
|
set: setPrimaryColor,
|
||||||
|
name: "Primary"
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
get: secondaryColor,
|
||||||
|
set: setSecondaryColor,
|
||||||
|
name: "Secondary"
|
||||||
|
},
|
||||||
|
tertiary: {
|
||||||
|
get: tertiaryColor,
|
||||||
|
set: setTertiaryColor,
|
||||||
|
name: "Tertiary"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const parsedID = colorwayID?.split("colorway:")[1];
|
const parsedID = colorwayID?.split("colorway:")[1];
|
||||||
if (parsedID) {
|
if (parsedID) {
|
||||||
const allEqual = (arr: any[]) => arr.every(v => v === arr[0]);
|
|
||||||
if (!parsedID) {
|
if (!parsedID) {
|
||||||
throw new Error("Please enter a Colorway ID");
|
throw new Error("Please enter a Colorway ID");
|
||||||
} else if (parsedID.length < 62) {
|
|
||||||
throw new Error("Invalid Colorway ID");
|
|
||||||
} else if (!hexToString(parsedID).includes(",")) {
|
} else if (!hexToString(parsedID).includes(",")) {
|
||||||
throw new Error("Invalid Colorway ID");
|
throw new Error("Invalid Colorway ID");
|
||||||
} else if (!allEqual(hexToString(parsedID).split(",").map((e: string) => e.match("#")!.length)) && hexToString(parsedID).split(",").map((e: string) => e.match("#")!.length)[0] !== 1) {
|
|
||||||
throw new Error("Invalid Colorway ID");
|
|
||||||
} else {
|
} else {
|
||||||
const colorArray: string[] = hexToString(parsedID).split(",");
|
const setColor = [
|
||||||
setAccentColor(colorArray[0].split("#")[1]);
|
setAccentColor,
|
||||||
setPrimaryColor(colorArray[1].split("#")[1]);
|
setPrimaryColor,
|
||||||
setSecondaryColor(colorArray[2].split("#")[1]);
|
setSecondaryColor,
|
||||||
setTertiaryColor(colorArray[3].split("#")[1]);
|
setTertiaryColor
|
||||||
|
];
|
||||||
|
hexToString(parsedID).split(/,#/).forEach((color: string, i: number) => setColor[i](colorToHex(color)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -100,62 +121,26 @@ export default function ({
|
||||||
value={colorwayName}
|
value={colorwayName}
|
||||||
onChange={setColorwayName}
|
onChange={setColorwayName}
|
||||||
/>
|
/>
|
||||||
|
<div className="colorwaysCreator-settingCat">
|
||||||
<Forms.FormTitle style={{ marginBottom: 0 }}>
|
<Forms.FormTitle style={{ marginBottom: 0 }}>
|
||||||
Colors:
|
Colors:
|
||||||
</Forms.FormTitle>
|
</Forms.FormTitle>
|
||||||
<div className="colorwayCreator-colorPreviews">
|
<div className="colorwayCreator-colorPreviews">
|
||||||
{presetColorArray.includes("primary") &&
|
{presetColorArray.map(presetColor => {
|
||||||
<ColorPicker
|
return <ColorPicker
|
||||||
label={<Text className="colorwaysPicker-colorLabel">Primary</Text>}
|
label={<Text className="colorwaysPicker-colorLabel">{colorProps[presetColor].name}</Text>}
|
||||||
color={parseInt(primaryColor, 16)}
|
color={parseInt(colorProps[presetColor].get, 16)}
|
||||||
onChange={(color: number) => {
|
onChange={(color: number) => {
|
||||||
let hexColor = color.toString(16);
|
let hexColor = color.toString(16);
|
||||||
while (hexColor.length < 6) {
|
while (hexColor.length < 6) {
|
||||||
hexColor = "0" + hexColor;
|
hexColor = "0" + hexColor;
|
||||||
}
|
}
|
||||||
setPrimaryColor(hexColor);
|
colorProps[presetColor].set(hexColor);
|
||||||
}}
|
}}
|
||||||
{...colorPickerProps}
|
{...colorPickerProps}
|
||||||
/>}
|
/>;
|
||||||
{presetColorArray.includes("secondary") &&
|
})}
|
||||||
<ColorPicker
|
</div>
|
||||||
label={<Text className="colorwaysPicker-colorLabel">Secondary</Text>}
|
|
||||||
color={parseInt(secondaryColor, 16)}
|
|
||||||
onChange={(color: number) => {
|
|
||||||
let hexColor = color.toString(16);
|
|
||||||
while (hexColor.length < 6) {
|
|
||||||
hexColor = "0" + hexColor;
|
|
||||||
}
|
|
||||||
setSecondaryColor(hexColor);
|
|
||||||
}}
|
|
||||||
{...colorPickerProps}
|
|
||||||
/>}
|
|
||||||
{presetColorArray.includes("tertiary") &&
|
|
||||||
<ColorPicker
|
|
||||||
label={<Text className="colorwaysPicker-colorLabel">Tertiary</Text>}
|
|
||||||
color={parseInt(tertiaryColor, 16)}
|
|
||||||
onChange={(color: number) => {
|
|
||||||
let hexColor = color.toString(16);
|
|
||||||
while (hexColor.length < 6) {
|
|
||||||
hexColor = "0" + hexColor;
|
|
||||||
}
|
|
||||||
setTertiaryColor(hexColor);
|
|
||||||
}}
|
|
||||||
{...colorPickerProps}
|
|
||||||
/>}
|
|
||||||
{presetColorArray.includes("accent") &&
|
|
||||||
<ColorPicker
|
|
||||||
label={<Text className="colorwaysPicker-colorLabel">Accent</Text>}
|
|
||||||
color={parseInt(accentColor, 16)}
|
|
||||||
onChange={(color: number) => {
|
|
||||||
let hexColor = color.toString(16);
|
|
||||||
while (hexColor.length < 6) {
|
|
||||||
hexColor = "0" + hexColor;
|
|
||||||
}
|
|
||||||
setAccentColor(hexColor);
|
|
||||||
}}
|
|
||||||
{...colorPickerProps}
|
|
||||||
/>}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={`colorwaysCreator-settingCat${collapsedSettings ? " colorwaysCreator-settingCat-collapsed" : ""}`}>
|
<div className={`colorwaysCreator-settingCat${collapsedSettings ? " colorwaysCreator-settingCat-collapsed" : ""}`}>
|
||||||
<div
|
<div
|
||||||
|
@ -231,11 +216,17 @@ export default function ({
|
||||||
discordSaturation
|
discordSaturation
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
(getPreset()[preset].id === "gradientType1" || getPreset()[preset].id === "gradientType2") ?
|
||||||
customColorwayCSS = getPreset(
|
customColorwayCSS = getPreset(
|
||||||
primaryColor,
|
primaryColor,
|
||||||
secondaryColor,
|
secondaryColor,
|
||||||
tertiaryColor,
|
tertiaryColor,
|
||||||
accentColor
|
accentColor
|
||||||
|
)[preset].preset(discordSaturation).full : customColorwayCSS = getPreset(
|
||||||
|
primaryColor,
|
||||||
|
secondaryColor,
|
||||||
|
tertiaryColor,
|
||||||
|
accentColor
|
||||||
)[preset].preset(discordSaturation);
|
)[preset].preset(discordSaturation);
|
||||||
}
|
}
|
||||||
const customColorway: Colorway = {
|
const customColorway: Colorway = {
|
||||||
|
@ -248,6 +239,13 @@ export default function ({
|
||||||
colors: presetColorArray,
|
colors: presetColorArray,
|
||||||
author: UserStore.getCurrentUser().username,
|
author: UserStore.getCurrentUser().username,
|
||||||
authorID: UserStore.getCurrentUser().id,
|
authorID: UserStore.getCurrentUser().id,
|
||||||
|
isGradient: getPreset()[preset].id === "gradientType1" || getPreset()[preset].id === "gradientType2",
|
||||||
|
linearGradient: (getPreset()[preset].id === "gradientType1" || getPreset()[preset].id === "gradientType2") ? getPreset(
|
||||||
|
primaryColor,
|
||||||
|
secondaryColor,
|
||||||
|
tertiaryColor,
|
||||||
|
accentColor
|
||||||
|
)[preset].preset(discordSaturation).base : null
|
||||||
};
|
};
|
||||||
const customColorwaysArray: Colorway[] = [customColorway];
|
const customColorwaysArray: Colorway[] = [customColorway];
|
||||||
DataStore.get("customColorways").then(
|
DataStore.get("customColorways").then(
|
||||||
|
@ -270,7 +268,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
function setAllColors({ accent, primary, secondary, tertiary }: { accent: string, primary: string, secondary: string, tertiary: string; }) {
|
function setAllColors({ accent, primary, secondary, tertiary }: { accent: string, primary: string, secondary: string, tertiary: string; }) {
|
||||||
setAccentColor(accent.split("#")[1]);
|
setAccentColor(accent.split("#")[1]);
|
||||||
|
@ -324,31 +322,8 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => {
|
onClick={() => openModal((props: any) => <InputColorwayIdModal modalProps={props} onColorwayId={colorwayID => {
|
||||||
let colorwayID: string;
|
|
||||||
function setColorwayID(e: string) {
|
|
||||||
colorwayID = e;
|
|
||||||
}
|
|
||||||
openModal(props => {
|
|
||||||
return (
|
|
||||||
<ModalRoot {...props} className="colorwaysCreator-noMinHeight">
|
|
||||||
<ModalContent className="colorwaysCreator-noHeader colorwaysCreator-noMinHeight">
|
|
||||||
<Forms.FormTitle>Colorway ID:</Forms.FormTitle>
|
|
||||||
<TextInput placeholder="Enter Colorway ID" onInput={e => setColorwayID(e.currentTarget.value)} />
|
|
||||||
</ModalContent>
|
|
||||||
<ModalFooter>
|
|
||||||
<Button
|
|
||||||
style={{ marginLeft: 8 }}
|
|
||||||
color={Button.Colors.BRAND}
|
|
||||||
size={Button.Sizes.MEDIUM}
|
|
||||||
look={Button.Looks.FILLED}
|
|
||||||
onClick={() => {
|
|
||||||
if (!colorwayID) {
|
|
||||||
throw new Error("Please enter a Colorway ID");
|
|
||||||
} else if (!hexToString(colorwayID).includes(",")) {
|
|
||||||
throw new Error("Invalid Colorway ID");
|
|
||||||
} else {
|
|
||||||
const setColor = [
|
const setColor = [
|
||||||
setAccentColor,
|
setAccentColor,
|
||||||
setPrimaryColor,
|
setPrimaryColor,
|
||||||
|
@ -356,28 +331,7 @@ export default function ({
|
||||||
setTertiaryColor
|
setTertiaryColor
|
||||||
];
|
];
|
||||||
hexToString(colorwayID).split(/,#/).forEach((color: string, i: number) => setColor[i](colorToHex(color)));
|
hexToString(colorwayID).split(/,#/).forEach((color: string, i: number) => setColor[i](colorToHex(color)));
|
||||||
props.onClose();
|
}} />)}
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Finish
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
style={{ marginLeft: 8 }}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
size={Button.Sizes.MEDIUM}
|
|
||||||
look={Button.Looks.FILLED}
|
|
||||||
onClick={() => {
|
|
||||||
props.onClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalRoot>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Enter Colorway ID
|
Enter Colorway ID
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -385,7 +339,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
modalProps.onClose();
|
modalProps.onClose();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a Discord client mod
|
|
||||||
* Copyright (c) 2024 Vendicated and contributors
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
return <div style={{
|
|
||||||
width: "100%",
|
|
||||||
height: 1,
|
|
||||||
borderTop: "thin solid var(--background-modifier-accent)",
|
|
||||||
marginTop: "var(--custom-margin-margin-medium)",
|
|
||||||
marginBottom: 20
|
|
||||||
}} />;
|
|
||||||
};
|
|
|
@ -140,7 +140,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const stringToHex = (str: string) => {
|
const stringToHex = (str: string) => {
|
||||||
let hex = "";
|
let hex = "";
|
||||||
|
@ -169,7 +169,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Clipboard.copy(colorwayProps["dc-import"]);
|
Clipboard.copy(colorwayProps["dc-import"]);
|
||||||
Toasts.show({
|
Toasts.show({
|
||||||
|
@ -185,7 +185,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const customColorways = await DataStore.get("customColorways");
|
const customColorways = await DataStore.get("customColorways");
|
||||||
const customColorwaysArray: Colorway[] = [];
|
const customColorwaysArray: Colorway[] = [];
|
||||||
|
@ -211,7 +211,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const colorwaySourceFiles = await DataStore.get(
|
const colorwaySourceFiles = await DataStore.get(
|
||||||
"colorwaySourceFiles"
|
"colorwaySourceFiles"
|
||||||
|
@ -251,7 +251,7 @@ export default function ({
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
look={Button.Looks.FILLED}
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
modalProps.onClose();
|
modalProps.onClose();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ModalContent, ModalFooter, ModalProps, ModalRoot } from "@utils/modal";
|
||||||
|
import { Button, Forms, TextInput, useState } from "@webpack/common";
|
||||||
|
|
||||||
|
import { hexToString } from "../utils";
|
||||||
|
|
||||||
|
export default function ({ modalProps, onColorwayId }: { modalProps: ModalProps, onColorwayId: (colorwayID: string) => void; }) {
|
||||||
|
const [colorwayID, setColorwayID] = useState<string>("");
|
||||||
|
return <ModalRoot {...modalProps} className="colorwaysCreator-noMinHeight">
|
||||||
|
<ModalContent className="colorwaysCreator-noHeader colorwaysCreator-noMinHeight">
|
||||||
|
<Forms.FormTitle>Colorway ID:</Forms.FormTitle>
|
||||||
|
<TextInput placeholder="Enter Colorway ID" onInput={e => setColorwayID(e.currentTarget.value)} />
|
||||||
|
</ModalContent>
|
||||||
|
<ModalFooter>
|
||||||
|
<Button
|
||||||
|
style={{ marginLeft: 8 }}
|
||||||
|
color={Button.Colors.BRAND}
|
||||||
|
size={Button.Sizes.MEDIUM}
|
||||||
|
look={Button.Looks.FILLED}
|
||||||
|
onClick={() => {
|
||||||
|
if (!colorwayID) {
|
||||||
|
throw new Error("Please enter a Colorway ID");
|
||||||
|
} else if (!hexToString(colorwayID).includes(",")) {
|
||||||
|
throw new Error("Invalid Colorway ID");
|
||||||
|
} else {
|
||||||
|
onColorwayId(colorwayID);
|
||||||
|
modalProps.onClose();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Finish
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style={{ marginLeft: 8 }}
|
||||||
|
color={Button.Colors.PRIMARY}
|
||||||
|
size={Button.Sizes.MEDIUM}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
|
onClick={() => modalProps.onClose()}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalRoot>;
|
||||||
|
}
|
|
@ -7,6 +7,8 @@
|
||||||
/* eslint-disable arrow-parens */
|
/* eslint-disable arrow-parens */
|
||||||
|
|
||||||
import * as DataStore from "@api/DataStore";
|
import * as DataStore from "@api/DataStore";
|
||||||
|
import { Flex } from "@components/Flex";
|
||||||
|
import { SettingsTab } from "@components/VencordSettings/shared";
|
||||||
import { ModalContent, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal";
|
import { ModalContent, ModalHeader, ModalProps, ModalRoot, openModal } from "@utils/modal";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import {
|
import {
|
||||||
|
@ -23,10 +25,11 @@ import {
|
||||||
useEffect,
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
} from "@webpack/common";
|
} from "@webpack/common";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
import { ColorwayCSS } from "..";
|
import { ColorwayCSS } from "..";
|
||||||
import { defaultColorwaySource, fallbackColorways } from "../constants";
|
import { defaultColorwaySource, fallbackColorways } from "../constants";
|
||||||
import { generateCss } from "../css";
|
import { generateCss, gradientBase } from "../css";
|
||||||
import { Colorway } from "../types";
|
import { Colorway } from "../types";
|
||||||
import { colorToHex } from "../utils";
|
import { colorToHex } from "../utils";
|
||||||
import ColorPickerModal from "./ColorPicker";
|
import ColorPickerModal from "./ColorPicker";
|
||||||
|
@ -36,10 +39,46 @@ import ColorwayInfoModal from "./InfoModal";
|
||||||
|
|
||||||
const { SelectionCircle } = findByPropsLazy("SelectionCircle");
|
const { SelectionCircle } = findByPropsLazy("SelectionCircle");
|
||||||
|
|
||||||
|
function SelectorContainer({ children, isSettings, modalProps }: { children: ReactNode, isSettings?: boolean, modalProps: ModalProps; }) {
|
||||||
|
if (!isSettings) {
|
||||||
|
return <ModalRoot {...modalProps} className="colorwaySelectorModal">
|
||||||
|
{children}
|
||||||
|
</ModalRoot>;
|
||||||
|
} else {
|
||||||
|
return <SettingsTab title="Colors">
|
||||||
|
<div className="colorwaysSettingsSelector-wrapper">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</SettingsTab>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectorHeader({ children, isSettings }: { children: ReactNode, isSettings?: boolean; }) {
|
||||||
|
if (!isSettings) {
|
||||||
|
return <ModalHeader>
|
||||||
|
{children}
|
||||||
|
</ModalHeader>;
|
||||||
|
} else {
|
||||||
|
return <Flex style={{ gap: "0" }}>
|
||||||
|
{children}
|
||||||
|
</Flex>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectorContent({ children, isSettings }: { children: ReactNode, isSettings?: boolean; }) {
|
||||||
|
if (!isSettings) {
|
||||||
|
return <ModalContent className="colorwaySelectorModalContent">{children}</ModalContent>;
|
||||||
|
} else {
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function ({
|
export default function ({
|
||||||
modalProps,
|
modalProps,
|
||||||
|
isSettings
|
||||||
}: {
|
}: {
|
||||||
modalProps: ModalProps;
|
modalProps: ModalProps,
|
||||||
|
isSettings?: boolean;
|
||||||
}): JSX.Element | any {
|
}): JSX.Element | any {
|
||||||
const [currentColorway, setCurrentColorway] = useState<string>("");
|
const [currentColorway, setCurrentColorway] = useState<string>("");
|
||||||
const [colorways, setColorways] = useState<Colorway[]>([]);
|
const [colorways, setColorways] = useState<Colorway[]>([]);
|
||||||
|
@ -179,8 +218,8 @@ export default function ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalRoot {...modalProps} className="colorwaySelectorModal">
|
<SelectorContainer modalProps={modalProps} isSettings={isSettings}>
|
||||||
<ModalHeader>
|
<SelectorHeader isSettings={isSettings}>
|
||||||
<Select className="colorwaySelector-pill colorwaySelector-pill_select" options={[{
|
<Select className="colorwaySelector-pill colorwaySelector-pill_select" options={[{
|
||||||
value: "all",
|
value: "all",
|
||||||
label: "All"
|
label: "All"
|
||||||
|
@ -221,6 +260,7 @@ export default function ({
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
style={{ marginLeft: "8px" }}
|
style={{ marginLeft: "8px" }}
|
||||||
id="colorway-refreshcolorway"
|
id="colorway-refreshcolorway"
|
||||||
onMouseEnter={isShown ? () => { } : onMouseEnter}
|
onMouseEnter={isShown ? () => { } : onMouseEnter}
|
||||||
|
@ -237,7 +277,7 @@ export default function ({
|
||||||
y="0px"
|
y="0px"
|
||||||
width="20"
|
width="20"
|
||||||
height="20"
|
height="20"
|
||||||
style={{ padding: "6px" }}
|
style={{ padding: "6px", boxSizing: "content-box" }}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
>
|
>
|
||||||
|
@ -255,11 +295,12 @@ export default function ({
|
||||||
</Popout>;
|
</Popout>;
|
||||||
}}
|
}}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip text="Open Settings">
|
{!isSettings ? <Tooltip text="Open Settings">
|
||||||
{({ onMouseEnter, onMouseLeave }) => <Button
|
{({ onMouseEnter, onMouseLeave }) => <Button
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
style={{ marginLeft: "8px" }}
|
style={{ marginLeft: "8px" }}
|
||||||
id="colorway-opensettings"
|
id="colorway-opensettings"
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
|
@ -274,18 +315,19 @@ export default function ({
|
||||||
role="img"
|
role="img"
|
||||||
width="20"
|
width="20"
|
||||||
height="20"
|
height="20"
|
||||||
style={{ padding: "6px" }}
|
style={{ padding: "6px", boxSizing: "content-box" }}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M19.738 10H22V14H19.739C19.498 14.931 19.1 15.798 18.565 16.564L20 18L18 20L16.565 18.564C15.797 19.099 14.932 19.498 14 19.738V22H10V19.738C9.069 19.498 8.203 19.099 7.436 18.564L6 20L4 18L5.436 16.564C4.901 15.799 4.502 14.932 4.262 14H2V10H4.262C4.502 9.068 4.9 8.202 5.436 7.436L4 6L6 4L7.436 5.436C8.202 4.9 9.068 4.502 10 4.262V2H14V4.261C14.932 4.502 15.797 4.9 16.565 5.435L18 3.999L20 5.999L18.564 7.436C19.099 8.202 19.498 9.069 19.738 10ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16Z" />
|
<path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M19.738 10H22V14H19.739C19.498 14.931 19.1 15.798 18.565 16.564L20 18L18 20L16.565 18.564C15.797 19.099 14.932 19.498 14 19.738V22H10V19.738C9.069 19.498 8.203 19.099 7.436 18.564L6 20L4 18L5.436 16.564C4.901 15.799 4.502 14.932 4.262 14H2V10H4.262C4.502 9.068 4.9 8.202 5.436 7.436L4 6L6 4L7.436 5.436C8.202 4.9 9.068 4.502 10 4.262V2H14V4.261C14.932 4.502 15.797 4.9 16.565 5.435L18 3.999L20 5.999L18.564 7.436C19.099 8.202 19.498 9.069 19.738 10ZM12 16C14.2091 16 16 14.2091 16 12C16 9.79086 14.2091 8 12 8C9.79086 8 8 9.79086 8 12C8 14.2091 9.79086 16 12 16Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</Button>}
|
</Button>}
|
||||||
</Tooltip>
|
</Tooltip> : <></>}
|
||||||
<Tooltip text="Create Colorway...">
|
<Tooltip text="Create Colorway...">
|
||||||
{({ onMouseEnter, onMouseLeave }) => <Button
|
{({ onMouseEnter, onMouseLeave }) => <Button
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
style={{ marginLeft: "8px" }}
|
style={{ marginLeft: "8px" }}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
|
@ -300,7 +342,7 @@ export default function ({
|
||||||
role="img"
|
role="img"
|
||||||
width="20"
|
width="20"
|
||||||
height="20"
|
height="20"
|
||||||
style={{ padding: "6px" }}
|
style={{ padding: "6px", boxSizing: "content-box" }}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
|
@ -315,32 +357,34 @@ export default function ({
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
style={{ marginLeft: "8px" }}
|
style={{ marginLeft: "8px" }}
|
||||||
id="colorway-opencolorstealer"
|
id="colorway-opencolorstealer"
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onClick={() => openModal((props) => <ColorPickerModal modalProps={props} />)}
|
onClick={() => openModal((props) => <ColorPickerModal modalProps={props} />)}
|
||||||
>
|
>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" style={{ padding: "6px" }} fill="currentColor" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" style={{ padding: "6px", boxSizing: "content-box" }} fill="currentColor" viewBox="0 0 16 16">
|
||||||
<path d="M12.433 10.07C14.133 10.585 16 11.15 16 8a8 8 0 1 0-8 8c1.996 0 1.826-1.504 1.649-3.08-.124-1.101-.252-2.237.351-2.92.465-.527 1.42-.237 2.433.07zM8 5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM5 6.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm.5 6.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
|
<path d="M12.433 10.07C14.133 10.585 16 11.15 16 8a8 8 0 1 0-8 8c1.996 0 1.826-1.504 1.649-3.08-.124-1.101-.252-2.237.351-2.92.465-.527 1.42-.237 2.433.07zM8 5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM5 6.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm.5 6.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
|
||||||
</svg>
|
</svg>
|
||||||
</Button>}
|
</Button>}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip text="Close">
|
{!isSettings ? <Tooltip text="Close">
|
||||||
{({ onMouseEnter, onMouseLeave }) => <Button
|
{({ onMouseEnter, onMouseLeave }) => <Button
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.PRIMARY}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
id="colorwaySelector-pill_closeSelector"
|
id="colorwaySelector-pill_closeSelector"
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
onClick={() => modalProps.onClose()}
|
onClick={() => modalProps.onClose()}
|
||||||
>
|
>
|
||||||
<CloseIcon style={{ padding: "6px" }} width={20} height={20} />
|
<CloseIcon style={{ padding: "6px", boxSizing: "content-box" }} width={20} height={20} />
|
||||||
</Button>}
|
</Button>}
|
||||||
</Tooltip>
|
</Tooltip> : <></>}
|
||||||
</ModalHeader>
|
</SelectorHeader>
|
||||||
<ModalContent className="colorwaySelectorModalContent">
|
<SelectorContent isSettings={isSettings}>
|
||||||
<div className="colorwaysLoader-barContainer"><div className="colorwaysLoader-bar" style={{ height: loaderHeight }} /></div>
|
<div className="colorwaysLoader-barContainer"><div className="colorwaysLoader-bar" style={{ height: loaderHeight }} /></div>
|
||||||
<ScrollerThin style={{ maxHeight: "450px" }} className="ColorwaySelectorWrapper">
|
<ScrollerThin style={{ maxHeight: "450px" }} className="ColorwaySelectorWrapper">
|
||||||
{visibleColorwayArray.length === 0 &&
|
{visibleColorwayArray.length === 0 &&
|
||||||
|
@ -364,52 +408,16 @@ export default function ({
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<Tooltip text={color.name}>
|
<Tooltip text={color.name}>
|
||||||
{({ onMouseEnter, onMouseLeave }) => <div
|
{({ onMouseEnter, onMouseLeave }) => {
|
||||||
className={"discordColorway" + (currentColorway === color.name ? "" : "")}
|
return (
|
||||||
|
<div
|
||||||
|
className="discordColorway"
|
||||||
id={"colorway-" + color.name}
|
id={"colorway-" + color.name}
|
||||||
data-last-official={ind + 1 === colorways.length}
|
data-last-official={
|
||||||
|
ind + 1 === colorways.length
|
||||||
|
}
|
||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="colorwayInfoIconContainer"
|
|
||||||
onClick={() => openModal((props) => <ColorwayInfoModal
|
|
||||||
modalProps={props}
|
|
||||||
colorwayProps={color}
|
|
||||||
discrimProps={customColorways.includes(color)}
|
|
||||||
loadUIProps={cached_loadUI}
|
|
||||||
/>)}
|
|
||||||
>
|
|
||||||
<div className="colorwayInfoIcon">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="16"
|
|
||||||
height="16"
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
>
|
|
||||||
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="colorwayCheckIconContainer">
|
|
||||||
<div className="colorwayCheckIcon">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<circle r="8" cx="12" cy="12" fill="var(--white-500)" />
|
|
||||||
<g fill="none" fill-rule="evenodd">
|
|
||||||
<path fill="var(--brand-500)" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="discordColorwayPreviewColorContainer"
|
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const [
|
const [
|
||||||
onDemandWays,
|
onDemandWays,
|
||||||
|
@ -428,14 +436,14 @@ export default function ({
|
||||||
DataStore.set("activeColorwayColors", color.colors);
|
DataStore.set("activeColorwayColors", color.colors);
|
||||||
DataStore.set("actveColorwayID", color.name);
|
DataStore.set("actveColorwayID", color.name);
|
||||||
if (onDemandWays) {
|
if (onDemandWays) {
|
||||||
const demandedColorway = generateCss(
|
const demandedColorway = !color.isGradient ? generateCss(
|
||||||
colorToHex(color.primary),
|
colorToHex(color.primary),
|
||||||
colorToHex(color.secondary),
|
colorToHex(color.secondary),
|
||||||
colorToHex(color.tertiary),
|
colorToHex(color.tertiary),
|
||||||
colorToHex(color.accent),
|
colorToHex(color.accent),
|
||||||
onDemandWaysTintedText,
|
onDemandWaysTintedText,
|
||||||
onDemandWaysDiscordSaturation
|
onDemandWaysDiscordSaturation
|
||||||
);
|
) : gradientBase(colorToHex(color.accent), onDemandWaysDiscordSaturation) + `:root:root {--custom-theme-background: linear-gradient(${color.linearGradient})}`;
|
||||||
DataStore.set("actveColorway", demandedColorway);
|
DataStore.set("actveColorway", demandedColorway);
|
||||||
ColorwayCSS.set(demandedColorway);
|
ColorwayCSS.set(demandedColorway);
|
||||||
} else {
|
} else {
|
||||||
|
@ -446,19 +454,59 @@ export default function ({
|
||||||
setCurrentColorway(await DataStore.get("actveColorwayID") as string);
|
setCurrentColorway(await DataStore.get("actveColorwayID") as string);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{colors.map((colorItm) => <div
|
<div
|
||||||
|
className="colorwayInfoIconContainer"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
openModal((props) => (
|
||||||
|
<ColorwayInfoModal
|
||||||
|
modalProps={
|
||||||
|
props
|
||||||
|
}
|
||||||
|
colorwayProps={
|
||||||
|
color
|
||||||
|
}
|
||||||
|
discrimProps={customColorways.includes(
|
||||||
|
color
|
||||||
|
)}
|
||||||
|
loadUIProps={cached_loadUI}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div className="discordColorwayPreviewColorContainer">
|
||||||
|
{!color.isGradient ? colors.map((colorItm) => <div
|
||||||
className="discordColorwayPreviewColor"
|
className="discordColorwayPreviewColor"
|
||||||
style={{ backgroundColor: color[colorItm] }}
|
style={{
|
||||||
/>)}
|
backgroundColor: color[colorItm],
|
||||||
|
}}
|
||||||
|
/>) : <div
|
||||||
|
className="discordColorwayPreviewColor"
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(${color.linearGradient})`,
|
||||||
|
}}
|
||||||
|
/>}
|
||||||
</div>
|
</div>
|
||||||
{currentColorway === color.name && <SelectionCircle />}
|
{currentColorway === color.name && <SelectionCircle />}
|
||||||
</div>}
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
</ScrollerThin>
|
</ScrollerThin>
|
||||||
</ModalContent >
|
</SelectorContent>
|
||||||
</ModalRoot >
|
</SelectorContainer >
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -125,35 +125,5 @@ export default function () {
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Forms.FormSection>
|
</Forms.FormSection>
|
||||||
<Forms.FormDivider className={Margins.top8 + " " + Margins.bottom8} />
|
|
||||||
<Forms.FormSection title="Developer Options:">
|
|
||||||
<Button
|
|
||||||
size={Button.Sizes.SMALL}
|
|
||||||
onClick={async () => {
|
|
||||||
const colorwaySourceFiles = await DataStore.get(
|
|
||||||
"colorwaySourceFiles"
|
|
||||||
);
|
|
||||||
const responses: Response[] = await Promise.all(
|
|
||||||
colorwaySourceFiles.map((url: string) =>
|
|
||||||
fetch(url)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const data = await Promise.all(
|
|
||||||
responses.map((res: Response) =>
|
|
||||||
res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; })
|
|
||||||
));
|
|
||||||
const colorwaysArr: Colorway[] = data.flatMap(json => json.url === defaultColorwaySource ? json.colorways : []);
|
|
||||||
|
|
||||||
colorwaysArr.forEach((color: Colorway) => {
|
|
||||||
if (IS_DISCORD_DESKTOP) {
|
|
||||||
DiscordNative.fileManager.saveWithDialog(generateCss(color.primary.split("#")[1] || "313338", color.secondary.split("#")[1] || "2b2d31", color.tertiary.split("#")[1] || "1e1f22", color.accent.split("#")[1] || "5865f2", true, true), `import_${color.name.replaceAll(" ", "-").replaceAll("'", "")}.css`);
|
|
||||||
} else {
|
|
||||||
saveFile(new File([generateCss(color.primary.split("#")[1] || "313338", color.secondary.split("#")[1] || "2b2d31", color.tertiary.split("#")[1] || "1e1f22", color.accent.split("#")[1] || "5865f2", true, true)], `import_${color.name.replaceAll(" ", "-").replaceAll("'", "")}.css`, { type: "text/plain;charset=utf-8" }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}>
|
|
||||||
Update all official Colorways and export
|
|
||||||
</Button>
|
|
||||||
</Forms.FormSection>
|
|
||||||
</SettingsTab>;
|
</SettingsTab>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,445 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a Discord client mod
|
|
||||||
* Copyright (c) 2023 Vendicated and contributors
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* eslint-disable arrow-parens */
|
|
||||||
|
|
||||||
import * as DataStore from "@api/DataStore";
|
|
||||||
import { Flex } from "@components/Flex";
|
|
||||||
import { SettingsTab } from "@components/VencordSettings/shared";
|
|
||||||
import { openModal } from "@utils/modal";
|
|
||||||
import { findByPropsLazy } from "@webpack";
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Forms,
|
|
||||||
Menu,
|
|
||||||
Popout,
|
|
||||||
Select,
|
|
||||||
TextInput,
|
|
||||||
Tooltip,
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from "@webpack/common";
|
|
||||||
|
|
||||||
import { ColorwayCSS } from "../..";
|
|
||||||
import { defaultColorwaySource, fallbackColorways } from "../../constants";
|
|
||||||
import { generateCss } from "../../css";
|
|
||||||
import { Colorway } from "../../types";
|
|
||||||
import { colorToHex } from "../../utils";
|
|
||||||
import ColorPickerModal from "../ColorPicker";
|
|
||||||
import CreatorModal from "../CreatorModal";
|
|
||||||
import ColorwayInfoModal from "../InfoModal";
|
|
||||||
|
|
||||||
const { SelectionCircle } = findByPropsLazy("SelectionCircle");
|
|
||||||
|
|
||||||
export default function ({
|
|
||||||
visibleTabProps = "all",
|
|
||||||
}: {
|
|
||||||
visibleTabProps?: string;
|
|
||||||
}): JSX.Element | any {
|
|
||||||
const [currentColorway, setCurrentColorway] = useState<string>("");
|
|
||||||
const [colorways, setColorways] = useState<Colorway[]>([]);
|
|
||||||
const [thirdPartyColorways, setThirdPartyColorways] = useState<Colorway[]>([]);
|
|
||||||
const [customColorways, setCustomColorways] = useState<Colorway[]>([]);
|
|
||||||
const [searchString, setSearchString] = useState<string>("");
|
|
||||||
const [loaderHeight, setLoaderHeight] = useState<string>("2px");
|
|
||||||
const [visibility, setVisibility] = useState<string>(visibleTabProps);
|
|
||||||
const [showReloadMenu, setShowReloadMenu] = useState(false);
|
|
||||||
let visibleColorwayArray: Colorway[];
|
|
||||||
|
|
||||||
switch (visibility) {
|
|
||||||
case "all":
|
|
||||||
visibleColorwayArray = [...colorways, ...thirdPartyColorways, ...customColorways];
|
|
||||||
break;
|
|
||||||
case "official":
|
|
||||||
visibleColorwayArray = [...colorways];
|
|
||||||
break;
|
|
||||||
case "3rdparty":
|
|
||||||
visibleColorwayArray = [...thirdPartyColorways];
|
|
||||||
break;
|
|
||||||
case "custom":
|
|
||||||
visibleColorwayArray = [...customColorways];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
visibleColorwayArray = [...colorways, ...thirdPartyColorways, ...customColorways];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadUI() {
|
|
||||||
const colorwaySourceFiles = await DataStore.get(
|
|
||||||
"colorwaySourceFiles"
|
|
||||||
);
|
|
||||||
const responses: Response[] = await Promise.all(
|
|
||||||
colorwaySourceFiles.map((url: string) =>
|
|
||||||
fetch(url)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const data = await Promise.all(
|
|
||||||
responses.map((res: Response) =>
|
|
||||||
res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; })
|
|
||||||
));
|
|
||||||
const colorways = data.flatMap((json) => json.url === defaultColorwaySource ? json.colorways : []);
|
|
||||||
const thirdPartyColorwaysArr = data.flatMap((json) => json.url !== defaultColorwaySource ? json.colorways : []);
|
|
||||||
const baseData = await DataStore.getMany([
|
|
||||||
"customColorways",
|
|
||||||
"actveColorwayID",
|
|
||||||
]);
|
|
||||||
setColorways(colorways || fallbackColorways);
|
|
||||||
setThirdPartyColorways(thirdPartyColorwaysArr);
|
|
||||||
setCustomColorways(baseData[0]);
|
|
||||||
setCurrentColorway(baseData[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cached_loadUI = useCallback(loadUI, [setColorways, setCustomColorways, setCurrentColorway]);
|
|
||||||
|
|
||||||
async function searchColorways(e: string) {
|
|
||||||
if (!e) {
|
|
||||||
cached_loadUI();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const colorwaySourceFiles = await DataStore.get("colorwaySourceFiles");
|
|
||||||
const data = await Promise.all(
|
|
||||||
colorwaySourceFiles.map((url: string) =>
|
|
||||||
fetch(url).then((res) => res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; }))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const colorways = data.flatMap((json) => json.url === defaultColorwaySource ? json.colorways : []);
|
|
||||||
const thirdPartyColorwaysArr = data.flatMap((json) => json.url !== defaultColorwaySource ? json.colorways : []);
|
|
||||||
const baseData = await DataStore.get("customColorways");
|
|
||||||
var results: Colorway[] = [];
|
|
||||||
(colorways || fallbackColorways).find((Colorway: Colorway) => {
|
|
||||||
if (Colorway.name.toLowerCase().includes(e.toLowerCase()))
|
|
||||||
results.push(Colorway);
|
|
||||||
});
|
|
||||||
var thirdPartyResults: Colorway[] = [];
|
|
||||||
(thirdPartyColorwaysArr).find((Colorway: Colorway) => {
|
|
||||||
if (Colorway.name.toLowerCase().includes(e.toLowerCase()))
|
|
||||||
thirdPartyResults.push(Colorway);
|
|
||||||
});
|
|
||||||
var customResults: Colorway[] = [];
|
|
||||||
baseData.find((Colorway: Colorway) => {
|
|
||||||
if (Colorway.name.toLowerCase().includes(e.toLowerCase()))
|
|
||||||
customResults.push(Colorway);
|
|
||||||
});
|
|
||||||
setColorways(results);
|
|
||||||
setThirdPartyColorways(thirdPartyResults);
|
|
||||||
setCustomColorways(customResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!searchString) {
|
|
||||||
cached_loadUI();
|
|
||||||
}
|
|
||||||
setLoaderHeight("0px");
|
|
||||||
}, [searchString]);
|
|
||||||
|
|
||||||
function ReloadPopout(onClose: () => void) {
|
|
||||||
return (
|
|
||||||
<Menu.Menu
|
|
||||||
navId="dc-reload-menu"
|
|
||||||
onClose={onClose}
|
|
||||||
>
|
|
||||||
<Menu.MenuItem
|
|
||||||
id="dc-force-reload"
|
|
||||||
label="Force Reload"
|
|
||||||
action={async () => {
|
|
||||||
setLoaderHeight("2px");
|
|
||||||
const colorwaySourceFiles = await DataStore.get(
|
|
||||||
"colorwaySourceFiles"
|
|
||||||
);
|
|
||||||
const responses: Response[] = await Promise.all(
|
|
||||||
colorwaySourceFiles.map((url: string) =>
|
|
||||||
fetch(url, { cache: "no-store" })
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const data = await Promise.all(
|
|
||||||
responses.map((res: Response) => {
|
|
||||||
setLoaderHeight("0px");
|
|
||||||
return res.json().then(dt => { return { colorways: dt.colorways, url: res.url }; }).catch(() => { return { colorways: [], url: res.url }; });
|
|
||||||
}
|
|
||||||
));
|
|
||||||
const colorways = data.flatMap((json) => json.url === defaultColorwaySource ? json.colorways : []);
|
|
||||||
const thirdPartyColorwaysArr = data.flatMap((json) => json.url !== defaultColorwaySource ? json.colorways : []);
|
|
||||||
const baseData = await DataStore.getMany([
|
|
||||||
"customColorways",
|
|
||||||
"actveColorwayID",
|
|
||||||
]);
|
|
||||||
setColorways(colorways || fallbackColorways);
|
|
||||||
setThirdPartyColorways(thirdPartyColorwaysArr);
|
|
||||||
setCustomColorways(baseData[0]);
|
|
||||||
setCurrentColorway(baseData[1]);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Menu.Menu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SettingsTab title="Colors">
|
|
||||||
<div className="colorwaysSettingsSelector-wrapper">
|
|
||||||
<Flex style={{ gap: "0" }}>
|
|
||||||
<Select className="colorwaySelector-pill colorwaySelector-pill_select" options={[{
|
|
||||||
value: "all",
|
|
||||||
label: "All"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "official",
|
|
||||||
label: "Official"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "3rdparty",
|
|
||||||
label: "3rd-Party"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "custom",
|
|
||||||
label: "Custom"
|
|
||||||
}]} select={value => {
|
|
||||||
setVisibility(value);
|
|
||||||
}} isSelected={value => visibility === value} serialize={String} />
|
|
||||||
<TextInput
|
|
||||||
inputClassName="colorwaySelector-searchInput"
|
|
||||||
className="colorwaySelector-search"
|
|
||||||
placeholder="Search for Colorways..."
|
|
||||||
value={searchString}
|
|
||||||
onChange={(e: string) => [searchColorways, setSearchString].forEach(t => t(e))}
|
|
||||||
/>
|
|
||||||
<Tooltip text="Refresh Colorways...">
|
|
||||||
{({ onMouseEnter, onMouseLeave }) => {
|
|
||||||
return <Popout
|
|
||||||
position="bottom"
|
|
||||||
align="right"
|
|
||||||
animation={Popout.Animation.NONE}
|
|
||||||
shouldShow={showReloadMenu}
|
|
||||||
onRequestClose={() => setShowReloadMenu(false)}
|
|
||||||
renderPopout={() => ReloadPopout(() => setShowReloadMenu(false))}
|
|
||||||
>
|
|
||||||
{(_, { isShown }) => (
|
|
||||||
<Button
|
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
|
||||||
size={Button.Sizes.ICON}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
style={{ marginLeft: "8px" }}
|
|
||||||
id="colorway-refreshcolorway"
|
|
||||||
onMouseEnter={isShown ? () => { } : onMouseEnter}
|
|
||||||
onMouseLeave={isShown ? () => { } : onMouseLeave}
|
|
||||||
onClick={() => {
|
|
||||||
setLoaderHeight("2px");
|
|
||||||
cached_loadUI().then(() => setLoaderHeight("0px"));
|
|
||||||
}}
|
|
||||||
onContextMenu={() => { onMouseLeave(); setShowReloadMenu(v => !v); }}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
style={{ padding: "6px", boxSizing: "content-box" }}
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="currentColor"
|
|
||||||
>
|
|
||||||
<rect
|
|
||||||
y="0"
|
|
||||||
fill="none"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
/>
|
|
||||||
<path d="M6.351,6.351C7.824,4.871,9.828,4,12,4c4.411,0,8,3.589,8,8h2c0-5.515-4.486-10-10-10 C9.285,2,6.779,3.089,4.938,4.938L3,3v6h6L6.351,6.351z" />
|
|
||||||
<path d="M17.649,17.649C16.176,19.129,14.173,20,12,20c-4.411,0-8-3.589-8-8H2c0,5.515,4.486,10,10,10 c2.716,0,5.221-1.089,7.062-2.938L21,21v-6h-6L17.649,17.649z" />
|
|
||||||
</svg>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Popout>;
|
|
||||||
}}
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip text="Create Colorway...">
|
|
||||||
{({ onMouseEnter, onMouseLeave }) => <Button
|
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
|
||||||
size={Button.Sizes.ICON}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
style={{ marginLeft: "8px" }}
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
onMouseLeave={onMouseLeave}
|
|
||||||
onClick={() => openModal((props) => <CreatorModal
|
|
||||||
modalProps={props}
|
|
||||||
loadUIProps={cached_loadUI}
|
|
||||||
/>)}
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
aria-hidden="true"
|
|
||||||
role="img"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
style={{ padding: "6px", boxSizing: "content-box" }}
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M20 11.1111H12.8889V4H11.1111V11.1111H4V12.8889H11.1111V20H12.8889V12.8889H20V11.1111Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</Button>}
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip text="Open Color Stealer">
|
|
||||||
{({ onMouseEnter, onMouseLeave }) => <Button
|
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
|
||||||
size={Button.Sizes.ICON}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
style={{ marginLeft: "8px" }}
|
|
||||||
id="colorway-opencolorstealer"
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
onMouseLeave={onMouseLeave}
|
|
||||||
onClick={() => openModal((props) => <ColorPickerModal modalProps={props} />)}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" style={{ padding: "6px", boxSizing: "content-box" }} fill="currentColor" viewBox="0 0 16 16">
|
|
||||||
<path d="M12.433 10.07C14.133 10.585 16 11.15 16 8a8 8 0 1 0-8 8c1.996 0 1.826-1.504 1.649-3.08-.124-1.101-.252-2.237.351-2.92.465-.527 1.42-.237 2.433.07zM8 5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM5 6.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm.5 6.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
|
|
||||||
</svg>
|
|
||||||
</Button>}
|
|
||||||
</Tooltip>
|
|
||||||
</Flex>
|
|
||||||
<div className="colorwaysLoader-barContainer"><div className="colorwaysLoader-bar" style={{ height: loaderHeight }} /></div>
|
|
||||||
<div className="ColorwaySelectorWrapper">
|
|
||||||
{visibleColorwayArray.length === 0 &&
|
|
||||||
<Forms.FormTitle
|
|
||||||
style={{
|
|
||||||
marginBottom: 0,
|
|
||||||
width: "100%",
|
|
||||||
textAlign: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
No colorways...
|
|
||||||
</Forms.FormTitle>
|
|
||||||
}
|
|
||||||
{visibleColorwayArray.map((color, ind) => {
|
|
||||||
var colors: Array<string> = color.colors || [
|
|
||||||
"accent",
|
|
||||||
"primary",
|
|
||||||
"secondary",
|
|
||||||
"tertiary",
|
|
||||||
];
|
|
||||||
return (
|
|
||||||
<Tooltip text={color.name}>
|
|
||||||
{({ onMouseEnter, onMouseLeave }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="discordColorway"
|
|
||||||
id={"colorway-" + color.name}
|
|
||||||
data-last-official={
|
|
||||||
ind + 1 === colorways.length
|
|
||||||
}
|
|
||||||
onMouseEnter={onMouseEnter}
|
|
||||||
onMouseLeave={onMouseLeave}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="colorwayInfoIconContainer"
|
|
||||||
onClick={() => {
|
|
||||||
openModal((props) => (
|
|
||||||
<ColorwayInfoModal
|
|
||||||
modalProps={
|
|
||||||
props
|
|
||||||
}
|
|
||||||
colorwayProps={
|
|
||||||
color
|
|
||||||
}
|
|
||||||
discrimProps={customColorways.includes(
|
|
||||||
color
|
|
||||||
)}
|
|
||||||
loadUIProps={cached_loadUI}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="colorwayInfoIcon">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="16"
|
|
||||||
height="16"
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 16 16"
|
|
||||||
>
|
|
||||||
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="colorwayCheckIconContainer">
|
|
||||||
<div className="colorwayCheckIcon">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="20"
|
|
||||||
height="20"
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<circle r="8" cx="12" cy="12" fill="var(--white-500)" />
|
|
||||||
<g fill="none" fill-rule="evenodd">
|
|
||||||
<path fill="var(--brand-500)" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="discordColorwayPreviewColorContainer"
|
|
||||||
onClick={async () => {
|
|
||||||
const [
|
|
||||||
onDemandWays,
|
|
||||||
onDemandWaysTintedText,
|
|
||||||
onDemandWaysDiscordSaturation
|
|
||||||
] = await DataStore.getMany([
|
|
||||||
"onDemandWays",
|
|
||||||
"onDemandWaysTintedText",
|
|
||||||
"onDemandWaysDiscordSaturation"
|
|
||||||
]);
|
|
||||||
if (currentColorway === color.name) {
|
|
||||||
DataStore.set("actveColorwayID", null);
|
|
||||||
DataStore.set("actveColorway", null);
|
|
||||||
ColorwayCSS.remove();
|
|
||||||
} else {
|
|
||||||
DataStore.set("activeColorwayColors", color.colors);
|
|
||||||
DataStore.set("actveColorwayID", color.name);
|
|
||||||
if (onDemandWays) {
|
|
||||||
const demandedColorway = generateCss(
|
|
||||||
colorToHex(color.primary),
|
|
||||||
colorToHex(color.secondary),
|
|
||||||
colorToHex(color.tertiary),
|
|
||||||
colorToHex(color.accent),
|
|
||||||
onDemandWaysTintedText,
|
|
||||||
onDemandWaysDiscordSaturation
|
|
||||||
);
|
|
||||||
DataStore.set("actveColorway", demandedColorway);
|
|
||||||
ColorwayCSS.set(demandedColorway);
|
|
||||||
} else {
|
|
||||||
DataStore.set("actveColorway", color["dc-import"]);
|
|
||||||
ColorwayCSS.set(color["dc-import"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCurrentColorway(await DataStore.get("actveColorwayID") as string);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{colors.map((colorItm) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="discordColorwayPreviewColor"
|
|
||||||
style={{
|
|
||||||
// prettier-ignore
|
|
||||||
backgroundColor: color[colorItm],
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
{currentColorway === color.name && <SelectionCircle />}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</SettingsTab>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -27,7 +27,6 @@ import { versionData } from "userplugins/discordColorways";
|
||||||
|
|
||||||
import { defaultColorwaySource, fallbackColorways, knownColorwaySources } from "../../constants";
|
import { defaultColorwaySource, fallbackColorways, knownColorwaySources } from "../../constants";
|
||||||
import { Colorway } from "../../types";
|
import { Colorway } from "../../types";
|
||||||
import Divider from "../Divider";
|
|
||||||
import { CloseIcon } from "../Icons";
|
import { CloseIcon } from "../Icons";
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
|
@ -165,7 +164,8 @@ export default function () {
|
||||||
&& <Button
|
&& <Button
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.TRANSPARENT}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
var sourcesArr: string[] = [];
|
var sourcesArr: string[] = [];
|
||||||
const colorwaySourceFilesArr = await DataStore.get("colorwaySourceFiles");
|
const colorwaySourceFilesArr = await DataStore.get("colorwaySourceFiles");
|
||||||
|
@ -183,7 +183,8 @@ export default function () {
|
||||||
<Button
|
<Button
|
||||||
innerClassName="colorwaysSettings-iconButtonInner"
|
innerClassName="colorwaysSettings-iconButtonInner"
|
||||||
size={Button.Sizes.ICON}
|
size={Button.Sizes.ICON}
|
||||||
color={Button.Colors.TRANSPARENT}
|
color={Button.Colors.PRIMARY}
|
||||||
|
look={Button.Looks.OUTLINED}
|
||||||
onClick={() => { Clipboard.copy(colorwaySourceFile); }}
|
onClick={() => { Clipboard.copy(colorwaySourceFile); }}
|
||||||
>
|
>
|
||||||
<CopyIcon width={20} height={20} />
|
<CopyIcon width={20} height={20} />
|
||||||
|
@ -191,7 +192,7 @@ export default function () {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Divider />
|
<Forms.FormDivider style={{ margin: "20px 0" }} />
|
||||||
<Forms.FormTitle tag="h5">Quick Switch</Forms.FormTitle>
|
<Forms.FormTitle tag="h5">Quick Switch</Forms.FormTitle>
|
||||||
<Switch
|
<Switch
|
||||||
value={colorsButtonVisibility}
|
value={colorsButtonVisibility}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ModalProps, ModalRoot, openModal } from "@utils/modal";
|
||||||
import {
|
import {
|
||||||
Forms,
|
Forms,
|
||||||
Text,
|
Text,
|
||||||
|
@ -31,15 +32,137 @@ export default function ({
|
||||||
previewCSS?: string;
|
previewCSS?: string;
|
||||||
}) {
|
}) {
|
||||||
const [collapsed, setCollapsed] = useState<boolean>(isCollapsed);
|
const [collapsed, setCollapsed] = useState<boolean>(isCollapsed);
|
||||||
|
function ThemePreview({
|
||||||
|
accent,
|
||||||
|
primary,
|
||||||
|
secondary,
|
||||||
|
tertiary,
|
||||||
|
isModal,
|
||||||
|
modalProps
|
||||||
|
}: {
|
||||||
|
accent: string,
|
||||||
|
primary: string,
|
||||||
|
secondary: string,
|
||||||
|
tertiary: string,
|
||||||
|
isModal?: boolean,
|
||||||
|
modalProps?: ModalProps;
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={
|
className="colorwaysPreview-wrapper"
|
||||||
`${collapsed === true
|
style={{ background: `var(--bg-overlay-app-frame, ${tertiary})` }}
|
||||||
? "colorwaysPreview colorwaysPreview-collapsed"
|
|
||||||
: "colorwaysPreview"
|
|
||||||
} ${className}`
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
|
<div className="colorwaysPreview-titlebar" />
|
||||||
|
<div className="colorwaysPreview-body">
|
||||||
|
<div className="colorwayPreview-guilds">
|
||||||
|
<div className="colorwayPreview-guild">
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-guildItem"
|
||||||
|
style={{ background: `var(--bg-guild-button, ${primary})` }}
|
||||||
|
onMouseEnter={e => e.currentTarget.style.background = accent}
|
||||||
|
onMouseLeave={e => e.currentTarget.style.background = `var(--bg-guild-button, ${primary})`}
|
||||||
|
onClick={() => {
|
||||||
|
if (isModal) {
|
||||||
|
modalProps?.onClose();
|
||||||
|
} else {
|
||||||
|
openModal((props: ModalProps) => <ModalRoot className="colorwaysPreview-modal" {...props}>
|
||||||
|
<style>
|
||||||
|
{previewCSS}
|
||||||
|
</style>
|
||||||
|
<ThemePreview accent={accent} primary={primary} secondary={secondary} tertiary={tertiary} isModal modalProps={props} />
|
||||||
|
</ModalRoot>);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isModal ? <CloseIcon style={{ color: "var(--header-secondary)" }} /> : <svg
|
||||||
|
aria-hidden="true"
|
||||||
|
role="img"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M19,3H14V5h5v5h2V5A2,2,0,0,0,19,3Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M19,19H14v2h5a2,2,0,0,0,2-2V14H19Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M3,5v5H5V5h5V3H5A2,2,0,0,0,3,5Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M5,14H3v5a2,2,0,0,0,2,2h5V19H5Z"
|
||||||
|
/>
|
||||||
|
</svg>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="colorwayPreview-guild">
|
||||||
|
<div className="colorwayPreview-guildSeparator" style={{ backgroundColor: primary }} />
|
||||||
|
</div>
|
||||||
|
<div className="colorwayPreview-guild">
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-guildItem"
|
||||||
|
style={{ background: `var(--bg-guild-button, ${primary})` }}
|
||||||
|
onMouseEnter={e => e.currentTarget.style.background = accent}
|
||||||
|
onMouseLeave={e => e.currentTarget.style.background = `var(--bg-guild-button, ${primary})`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="colorwayPreview-guild">
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-guildItem"
|
||||||
|
style={{ background: `var(--bg-guild-button, ${primary})` }}
|
||||||
|
onMouseEnter={e => e.currentTarget.style.background = accent}
|
||||||
|
onMouseLeave={e => e.currentTarget.style.background = `var(--bg-guild-button, ${primary})`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="colorwayPreview-channels" style={{ background: `var(--bg-overlay-3, ${secondary})` }}>
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-userArea"
|
||||||
|
style={{
|
||||||
|
background: `var(--bg-secondary-alt, hsl(${HexToHSL(secondary)[0]} ${HexToHSL(secondary)[1]}% ${Math.max(HexToHSL(secondary)[2] - 3.6, 0)}%))`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="colorwayPreview-filler" />
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-topShadow"
|
||||||
|
style={{
|
||||||
|
"--primary-900-hsl": `${HexToHSL(tertiary)[0]} ${HexToHSL(tertiary)[1]}% ${Math.max(HexToHSL(tertiary)[2] - (3.6 * 6), 0)}%`,
|
||||||
|
"--primary-500-hsl": `${HexToHSL(primary)[0]} ${HexToHSL(primary)[1]}% ${Math.min(HexToHSL(primary)[2] + (3.6 * 3), 100)}%`
|
||||||
|
} as React.CSSProperties}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
tag="div"
|
||||||
|
variant="text-md/semibold"
|
||||||
|
lineClamp={1}
|
||||||
|
selectable={false}
|
||||||
|
>
|
||||||
|
Preview
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="colorwayPreview-chat" style={{ background: `var(--bg-overlay-chat, ${primary})` }}>
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-chatBox"
|
||||||
|
style={{
|
||||||
|
background: `var(--bg-overlay-3, hsl(${HexToHSL(primary)[0]} ${HexToHSL(primary)[1]}% ${Math.min(HexToHSL(primary)[2] + 3.6, 100)}%))`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="colorwayPreview-filler" />
|
||||||
|
<div
|
||||||
|
className="colorwayPreview-topShadow"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={`${collapsed ? "colorwaysPreview colorwaysPreview-collapsed" : "colorwaysPreview"} ${className || ""}`}>
|
||||||
<div
|
<div
|
||||||
className="colorwaysCreator-settingItm colorwaysCreator-settingHeader"
|
className="colorwaysCreator-settingItm colorwaysCreator-settingHeader"
|
||||||
onClick={() => setCollapsed(!collapsed)}
|
onClick={() => setCollapsed(!collapsed)}
|
||||||
|
@ -80,143 +203,3 @@ export default function ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ThemePreview({
|
|
||||||
accent,
|
|
||||||
primary,
|
|
||||||
secondary,
|
|
||||||
tertiary,
|
|
||||||
previewCSS
|
|
||||||
}: {
|
|
||||||
accent: string,
|
|
||||||
primary: string,
|
|
||||||
secondary: string,
|
|
||||||
tertiary: string,
|
|
||||||
previewCSS?: string;
|
|
||||||
}) {
|
|
||||||
const [isFullscreen, setIsFullscreen] = useState<boolean>(false);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="colorwaysPreview-container"
|
|
||||||
>
|
|
||||||
<style>
|
|
||||||
{previewCSS}
|
|
||||||
</style>
|
|
||||||
<div
|
|
||||||
className="colorwaysPreview-wrapper"
|
|
||||||
style={{ backgroundColor: tertiary }}
|
|
||||||
>
|
|
||||||
<div className="colorwaysPreview-titlebar" />
|
|
||||||
<div className="colorwaysPreview-body">
|
|
||||||
<div className="colorwayPreview-guilds">
|
|
||||||
<div className="colorwayPreview-guild">
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-guildItem"
|
|
||||||
style={{ backgroundColor: primary }}
|
|
||||||
onMouseEnter={e => e.currentTarget.style.backgroundColor = accent}
|
|
||||||
onMouseLeave={e => e.currentTarget.style.backgroundColor = primary}
|
|
||||||
onClick={e => {
|
|
||||||
if (!document.fullscreenElement) {
|
|
||||||
e.currentTarget
|
|
||||||
.parentElement
|
|
||||||
?.parentElement
|
|
||||||
?.parentElement
|
|
||||||
?.parentElement
|
|
||||||
?.requestFullscreen();
|
|
||||||
} else {
|
|
||||||
document.exitFullscreen();
|
|
||||||
}
|
|
||||||
setIsFullscreen(!isFullscreen);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{isFullscreen ? <CloseIcon /> : <svg
|
|
||||||
aria-hidden="true"
|
|
||||||
role="img"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M19,3H14V5h5v5h2V5A2,2,0,0,0,19,3Z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M19,19H14v2h5a2,2,0,0,0,2-2V14H19Z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M3,5v5H5V5h5V3H5A2,2,0,0,0,3,5Z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M5,14H3v5a2,2,0,0,0,2,2h5V19H5Z"
|
|
||||||
/>
|
|
||||||
</svg>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="colorwayPreview-guild">
|
|
||||||
<div className="colorwayPreview-guildSeparator" style={{ backgroundColor: primary }} />
|
|
||||||
</div>
|
|
||||||
<div className="colorwayPreview-guild">
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-guildItem"
|
|
||||||
style={{ backgroundColor: primary }}
|
|
||||||
onMouseEnter={e => { e.currentTarget.style.backgroundColor = accent; }}
|
|
||||||
onMouseLeave={e => { e.currentTarget.style.backgroundColor = primary; }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="colorwayPreview-guild">
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-guildItem"
|
|
||||||
style={{ backgroundColor: primary }}
|
|
||||||
onMouseEnter={e => { e.currentTarget.style.backgroundColor = accent; }}
|
|
||||||
onMouseLeave={e => { e.currentTarget.style.backgroundColor = primary; }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="colorwayPreview-channels" style={{ backgroundColor: secondary }}>
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-userArea"
|
|
||||||
style={{
|
|
||||||
backgroundColor: "hsl(" + HexToHSL(secondary)[0] + " " + HexToHSL(secondary)[1] + "% " + Math.max(HexToHSL(secondary)[2] - 3.6, 0) + "%)"
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="colorwayPreview-filler" />
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-topShadow"
|
|
||||||
style={{
|
|
||||||
"--primary-900-hsl": `${HexToHSL(tertiary)[0]} ${HexToHSL(tertiary)[1]}% ${Math.max(HexToHSL(tertiary)[2] - (3.6 * 6), 0)}%`,
|
|
||||||
"--primary-500-hsl": `${HexToHSL(primary)[0]} ${HexToHSL(primary)[1]}% ${Math.min(HexToHSL(primary)[2] + (3.6 * 3), 100)}%`
|
|
||||||
} as React.CSSProperties}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
tag="div"
|
|
||||||
variant="text-md/semibold"
|
|
||||||
lineClamp={1}
|
|
||||||
selectable={false}
|
|
||||||
>
|
|
||||||
Preview
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="colorwayPreview-chat" style={{ backgroundColor: primary }}>
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-chatBox"
|
|
||||||
style={{
|
|
||||||
backgroundColor: "hsl(" + HexToHSL(primary)[0] + " " + HexToHSL(primary)[1] + "% " + Math.min(HexToHSL(primary)[2] + 3.6, 100) + "%)"
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div className="colorwayPreview-filler" />
|
|
||||||
<div
|
|
||||||
className="colorwayPreview-topShadow"
|
|
||||||
style={{
|
|
||||||
"--primary-900-hsl": `${HexToHSL(tertiary)[0]} ${HexToHSL(tertiary)[1]}% ${Math.max(HexToHSL(tertiary)[2] - (3.6 * 6), 0)}%`
|
|
||||||
} as React.CSSProperties}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -315,3 +315,10 @@ export const knownThemeVars = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const mainColors = [
|
||||||
|
{ name: "accent", title: "Accent", var: "--brand-experiment" },
|
||||||
|
{ name: "primary", title: "Primary", var: "--background-primary" },
|
||||||
|
{ name: "secondary", title: "Secondary", var: "--background-secondary" },
|
||||||
|
{ name: "tertiary", title: "Tertiary", var: "--background-tertiary" }
|
||||||
|
];
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import { Plugins } from "Vencord";
|
import { Plugins } from "Vencord";
|
||||||
|
|
||||||
import { colorToHex, HexToHSL } from "./utils";
|
import { HexToHSL } from "./utils";
|
||||||
|
|
||||||
export const colorVariables: string[] = [
|
export const colorVariables: string[] = [
|
||||||
"brand-100",
|
"brand-100",
|
||||||
|
@ -290,9 +290,73 @@ const BrandLightDiffs = {
|
||||||
900: -61.6
|
900: -61.6
|
||||||
};
|
};
|
||||||
|
|
||||||
function gradientBase(accentColor?: string, discordSaturation = false) {
|
export const pureGradientBase = `
|
||||||
return `@import url(//dablulite.github.io/css-snippets/NoLightInDark/import.css);
|
.theme-dark :is(.colorwaysPreview-modal, .colorwaysPreview) {
|
||||||
@import url(//dablulite.github.io/css-snippets/NitroThemesFix/import.css);
|
--bg-overlay-color: 0 0 0;
|
||||||
|
--bg-overlay-color-inverse: 255 255 255;
|
||||||
|
--bg-overlay-opacity-1: 0.85;
|
||||||
|
--bg-overlay-opacity-2: 0.8;
|
||||||
|
--bg-overlay-opacity-3: 0.7;
|
||||||
|
--bg-overlay-opacity-4: 0.5;
|
||||||
|
--bg-overlay-opacity-5: 0.4;
|
||||||
|
--bg-overlay-opacity-6: 0.1;
|
||||||
|
--bg-overlay-opacity-hover: 0.5;
|
||||||
|
--bg-overlay-opacity-hover-inverse: 0.08;
|
||||||
|
--bg-overlay-opacity-active: 0.45;
|
||||||
|
--bg-overlay-opacity-active-inverse: 0.1;
|
||||||
|
--bg-overlay-opacity-selected: 0.4;
|
||||||
|
--bg-overlay-opacity-selected-inverse: 0.15;
|
||||||
|
--bg-overlay-opacity-chat: 0.8;
|
||||||
|
--bg-overlay-opacity-home: 0.85;
|
||||||
|
--bg-overlay-opacity-home-card: 0.8;
|
||||||
|
--bg-overlay-opacity-app-frame: var(--bg-overlay-opacity-4);
|
||||||
|
--bg-guild-button: rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6));
|
||||||
|
--bg-secondary-alt: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-chat-header: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
}
|
||||||
|
.theme-light :is(.colorwaysPreview-modal, .colorwaysPreview) {
|
||||||
|
--bg-overlay-color: 255 255 255;
|
||||||
|
--bg-overlay-color-inverse: 0 0 0;
|
||||||
|
--bg-overlay-opacity-1: 0.9;
|
||||||
|
--bg-overlay-opacity-2: 0.8;
|
||||||
|
--bg-overlay-opacity-3: 0.7;
|
||||||
|
--bg-overlay-opacity-4: 0.6;
|
||||||
|
--bg-overlay-opacity-5: 0.3;
|
||||||
|
--bg-overlay-opacity-6: 0.15;
|
||||||
|
--bg-overlay-opacity-hover: 0.7;
|
||||||
|
--bg-overlay-opacity-hover-inverse: 0.02;
|
||||||
|
--bg-overlay-opacity-active: 0.65;
|
||||||
|
--bg-overlay-opacity-active-inverse: 0.03;
|
||||||
|
--bg-overlay-opacity-selected: 0.6;
|
||||||
|
--bg-overlay-opacity-selected-inverse: 0.04;
|
||||||
|
--bg-overlay-opacity-chat: 0.9;
|
||||||
|
--bg-overlay-opacity-home: 0.7;
|
||||||
|
--bg-overlay-opacity-home-card: 0.9;
|
||||||
|
--bg-overlay-opacity-app-frame: var(--bg-overlay-opacity-5);
|
||||||
|
--bg-guild-button: rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3));
|
||||||
|
--bg-secondary-alt: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-chat-header: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
}
|
||||||
|
.colorwaysPreview-modal,
|
||||||
|
.colorwaysPreview {
|
||||||
|
--bg-overlay-1: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-1))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-2: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-2))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-3: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-3))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-4: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-4)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-4))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-5: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-5)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-5))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-6: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-6))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-hover: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-hover-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-hover-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-hover)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-hover))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-active: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-active-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-active-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-active)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-active))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-selected: linear-gradient(rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-selected-inverse)),rgb(var(--bg-overlay-color-inverse)/var(--bg-overlay-opacity-selected-inverse))) fixed 0 0/cover,linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-selected)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-selected))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-chat: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-home: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-home-card: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
--bg-overlay-app-frame: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame))) fixed 0 0/cover,var(--gradient-theme-bg) fixed 0 0/cover;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
|
||||||
|
export function gradientBase(accentColor?: string, discordSaturation = false) {
|
||||||
|
return `@import url(//dablulite.github.io/css-snippets/NitroThemesFix/import.css);
|
||||||
.theme-dark {
|
.theme-dark {
|
||||||
--bg-overlay-color: 0 0 0;
|
--bg-overlay-color: 0 0 0;
|
||||||
--bg-overlay-color-inverse: 255 255 255;
|
--bg-overlay-color-inverse: 255 255 255;
|
||||||
|
@ -401,14 +465,11 @@ function gradientBase(accentColor?: string, discordSaturation = false) {
|
||||||
--bg-overlay-chat: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
--bg-overlay-chat: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-chat))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
||||||
--bg-overlay-home: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
--bg-overlay-home: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
||||||
--bg-overlay-home-card: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
--bg-overlay-home-card: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-home-card))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
||||||
--bg-overlay-app-frame: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;`;
|
--bg-overlay-app-frame: linear-gradient(rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame)),rgb(var(--bg-overlay-color)/var(--bg-overlay-opacity-app-frame))) fixed 0 0/cover,var(--custom-theme-background) fixed 0 0/cover;
|
||||||
|
}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateCss(primaryColor: string, secondaryColor: string, tertiaryColor: string, accentColor: string, tintedText: boolean, discordSaturation: boolean) {
|
export function generateCss(primaryColor: string, secondaryColor: string, tertiaryColor: string, accentColor: string, tintedText: boolean, discordSaturation: boolean) {
|
||||||
primaryColor = colorToHex(primaryColor);
|
|
||||||
secondaryColor = colorToHex(secondaryColor);
|
|
||||||
tertiaryColor = colorToHex(tertiaryColor);
|
|
||||||
accentColor = colorToHex(accentColor);
|
|
||||||
const colorwayCss = `/*Automatically Generated - Colorway Creator V${(Plugins.plugins.DiscordColorways as any).creatorVersion}*/
|
const colorwayCss = `/*Automatically Generated - Colorway Creator V${(Plugins.plugins.DiscordColorways as any).creatorVersion}*/
|
||||||
:root:root {
|
:root:root {
|
||||||
--brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[100])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)};
|
--brand-100-hsl: ${HexToHSL("#" + accentColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + accentColor)[1] / 100) * (100 + BrandSatDiffs[100])) * 10) / 10 : HexToHSL("#" + accentColor)[1]}%) ${Math.max(Math.round((HexToHSL("#" + accentColor)[2] + BrandLightDiffs[100]) * 10) / 10, 0)};
|
||||||
|
@ -446,7 +507,9 @@ export function generateCss(primaryColor: string, secondaryColor: string, tertia
|
||||||
--primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%;
|
--primary-600-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${HexToHSL("#" + primaryColor)[2]}%;
|
||||||
--primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%;
|
--primary-560-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + 3.6, 100)}%;
|
||||||
--primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}%;
|
--primary-530-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[530])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 2), 100)}%;
|
||||||
--primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%;${tintedText ? `\n --primary-460-hsl: 0 calc(var(--saturation-factor, 1)*0%) 50%;
|
--primary-500-hsl: ${HexToHSL("#" + primaryColor)[0]} calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[500])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%) ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%;
|
||||||
|
--interactive-muted: hsl(${HexToHSL("#" + primaryColor)[0]} 0% ${Math.min(HexToHSL("#" + primaryColor)[2] + (3.6 * 3), 100)}%);
|
||||||
|
${tintedText ? `--primary-460-hsl: 0 calc(var(--saturation-factor, 1)*0%) 50%;
|
||||||
--primary-430: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[430])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")};
|
--primary-430: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[430])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")};
|
||||||
--primary-400: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[400])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")};
|
--primary-400: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[400])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")};
|
||||||
--primary-360: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[360])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")};` : ""}
|
--primary-360: ${HexToHSL("#" + secondaryColor)[0] === 0 ? "gray" : ((HexToHSL("#" + secondaryColor)[2] < 80) ? "hsl(" + HexToHSL("#" + secondaryColor)[0] + `, calc(var(--saturation-factor, 1)*${discordSaturation ? Math.round(((HexToHSL("#" + primaryColor)[1] / 100) * (100 + PrimarySatDiffs[360])) * 10) / 10 : HexToHSL("#" + primaryColor)[1]}%), 90%)` : "hsl(" + HexToHSL("#" + secondaryColor)[0] + ", calc(var(--saturation-factor, 1)*100%), 20%)")};` : ""}
|
||||||
|
@ -635,15 +698,22 @@ export function getPreset(primaryColor?: string, secondaryColor?: string, tertia
|
||||||
}
|
}
|
||||||
|
|
||||||
function gradientType1(discordSaturation = false) {
|
function gradientType1(discordSaturation = false) {
|
||||||
return `${gradientBase(accentColor, discordSaturation)}
|
return {
|
||||||
|
full: `${gradientBase(accentColor, discordSaturation)}
|
||||||
|
:root:root {
|
||||||
--custom-theme-background: linear-gradient(239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%);
|
--custom-theme-background: linear-gradient(239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%);
|
||||||
}`;
|
}`,
|
||||||
|
base: `239.16deg, #${primaryColor} 10.39%, #${secondaryColor} 26.87%, #${tertiaryColor} 48.31%, hsl(${HexToHSL("#" + secondaryColor)[0]} calc(var(--saturation-factor, 1)*${HexToHSL("#" + secondaryColor)[1]}%) ${Math.min(HexToHSL("#" + secondaryColor)[2] + 3.6, 100)}%) 64.98%, #${primaryColor} 92.5%`
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function gradientType2(discordSaturation = false) {
|
function gradientType2(discordSaturation = false) {
|
||||||
return `${gradientBase(accentColor, discordSaturation)}
|
return {
|
||||||
|
full: `${gradientBase(accentColor, discordSaturation)}
|
||||||
|
:root:root {
|
||||||
--custom-theme-background: linear-gradient(48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%);
|
--custom-theme-background: linear-gradient(48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%);
|
||||||
}`;
|
}`, base: `48.17deg, #${primaryColor} 11.21%, #${secondaryColor} 61.92%`
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function hueRotation(discordSaturation = false) {
|
function hueRotation(discordSaturation = false) {
|
||||||
|
|
|
@ -19,10 +19,9 @@ import {
|
||||||
import ColorPickerModal from "./components/ColorPicker";
|
import ColorPickerModal from "./components/ColorPicker";
|
||||||
import ColorwaysButton from "./components/ColorwaysButton";
|
import ColorwaysButton from "./components/ColorwaysButton";
|
||||||
import CreatorModal from "./components/CreatorModal";
|
import CreatorModal from "./components/CreatorModal";
|
||||||
import SelectorModal from "./components/SelectorModal";
|
import Selector from "./components/Selector";
|
||||||
import ManageColorwaysPage from "./components/SettingsTabs/ManageColorwaysPage";
|
import ManageColorwaysPage from "./components/SettingsTabs/ManageColorwaysPage";
|
||||||
import OnDemandWaysPage from "./components/SettingsTabs/OnDemandPage";
|
import OnDemandWaysPage from "./components/SettingsTabs/OnDemandPage";
|
||||||
import SelectorPage from "./components/SettingsTabs/SelectorPage";
|
|
||||||
import SettingsPage from "./components/SettingsTabs/SettingsPage";
|
import SettingsPage from "./components/SettingsTabs/SettingsPage";
|
||||||
import Spinner from "./components/Spinner";
|
import Spinner from "./components/Spinner";
|
||||||
import { defaultColorwaySource } from "./constants";
|
import { defaultColorwaySource } from "./constants";
|
||||||
|
@ -95,8 +94,8 @@ export const ColorwayCSS = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const versionData = {
|
export const versionData = {
|
||||||
pluginVersion: "5.6.2",
|
pluginVersion: "5.6.4.2",
|
||||||
creatorVersion: "1.18.1",
|
creatorVersion: "1.18.3",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
|
@ -111,7 +110,7 @@ export default definePlugin({
|
||||||
pluginVersion: versionData.pluginVersion,
|
pluginVersion: versionData.pluginVersion,
|
||||||
creatorVersion: versionData.creatorVersion,
|
creatorVersion: versionData.creatorVersion,
|
||||||
toolboxActions: {
|
toolboxActions: {
|
||||||
"Change Colorway": () => openModal(props => <SelectorModal modalProps={props} />),
|
"Change Colorway": () => openModal(props => <Selector modalProps={props} />),
|
||||||
"Open Colorway Creator": () => openModal(props => <CreatorModal modalProps={props} />),
|
"Open Colorway Creator": () => openModal(props => <CreatorModal modalProps={props} />),
|
||||||
"Open Color Stealer": () => openModal(props => <ColorPickerModal modalProps={props} />),
|
"Open Color Stealer": () => openModal(props => <ColorPickerModal modalProps={props} />),
|
||||||
"Open Settings": () => SettingsRouter.open("ColorwaysSettings"),
|
"Open Settings": () => SettingsRouter.open("ColorwaysSettings"),
|
||||||
|
@ -152,12 +151,12 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
set ColorPicker(e) {
|
set ColorPicker(e) {
|
||||||
ColorPicker = e;
|
ColorPicker = e;
|
||||||
},
|
},
|
||||||
|
|
||||||
makeSettingsCategories(SectionTypes: Record<string, unknown>) {
|
makeSettingsCategories(SectionTypes: Record<string, unknown>) {
|
||||||
console.log(SectionTypes);
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
section: SectionTypes.HEADER,
|
section: SectionTypes.HEADER,
|
||||||
|
@ -167,7 +166,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
section: "ColorwaysSelector",
|
section: "ColorwaysSelector",
|
||||||
label: "Colorways",
|
label: "Colorways",
|
||||||
element: SelectorPage,
|
element: () => <Selector isSettings modalProps={{ onClose: () => new Promise(() => true), transitionState: 1 }} />,
|
||||||
className: "dc-colorway-selector"
|
className: "dc-colorway-selector"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -202,22 +201,20 @@ export default definePlugin({
|
||||||
enableStyle(style);
|
enableStyle(style);
|
||||||
ColorwayCSS.set((await DataStore.get("actveColorway")) || "");
|
ColorwayCSS.set((await DataStore.get("actveColorway")) || "");
|
||||||
|
|
||||||
addAccessory("colorways-btn", props => {
|
addAccessory("colorways-btn", props => String(props.message.content).match(/colorway:[0-9a-f]{0,100}/) ? <Button
|
||||||
if (String(props.message.content).match(/colorway:[0-9a-f]{0,71}/))
|
onClick={() => openModal(modalProps => <CreatorModal
|
||||||
return <Button onClick={() => {
|
modalProps={modalProps}
|
||||||
openModal(propss => (
|
colorwayID={String(props.message.content).match(/colorway:[0-9a-f]{0,100}/)![0]}
|
||||||
<CreatorModal
|
/>)}
|
||||||
modalProps={propss}
|
size={Button.Sizes.SMALL}
|
||||||
colorwayID={String(props.message.content).match(/colorway:[0-9a-f]{0,71}/)![0]}
|
color={Button.Colors.PRIMARY}
|
||||||
/>
|
look={Button.Looks.OUTLINED}
|
||||||
));
|
>
|
||||||
}} size={Button.Sizes.SMALL} color={Button.Colors.PRIMARY}>Add this Colorway...</Button>;
|
Add this Colorway...
|
||||||
return null;
|
</Button> : null);
|
||||||
});
|
|
||||||
},
|
},
|
||||||
stop() {
|
stop() {
|
||||||
removeServerListElement(ServerListRenderPosition.In, this.ColorwaysButton);
|
removeServerListElement(ServerListRenderPosition.In, this.ColorwaysButton);
|
||||||
|
|
||||||
disableStyle(style);
|
disableStyle(style);
|
||||||
ColorwayCSS.remove();
|
ColorwayCSS.remove();
|
||||||
removeAccessory("colorways-btn");
|
removeAccessory("colorways-btn");
|
||||||
|
|
|
@ -47,85 +47,26 @@
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
box-shadow: 0 0 0 1px var(--interactive-normal);
|
box-shadow: 0 0 0 1.5px var(--interactive-normal);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discordColorway::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -2px;
|
|
||||||
left: -2px;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: .15s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorway.active::before {
|
|
||||||
box-shadow: inset 0 0 0 2px var(--brand-500), inset 0 0 0 4px var(--background-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColor {
|
.discordColorwayPreviewColor {
|
||||||
width: calc(50% - 2px);
|
width: 50%;
|
||||||
height: calc(50% - 2px);
|
height: 50%;
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColor:first-child {
|
|
||||||
margin-top: 2px;
|
|
||||||
margin-left: 2px;
|
|
||||||
border-top-left-radius: 52px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColor:nth-child(2) {
|
|
||||||
margin-top: 2px;
|
|
||||||
margin-right: 2px;
|
|
||||||
border-top-right-radius: 52px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColor:nth-child(3) {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
margin-left: 2px;
|
|
||||||
border-bottom-left-radius: 52px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColor:nth-child(4) {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
margin-right: 2px;
|
|
||||||
border-bottom-right-radius: 52px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(2)))>.discordColorwayPreviewColor {
|
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(2)))>.discordColorwayPreviewColor {
|
||||||
height: calc(100% - 4px);
|
height: 100%;
|
||||||
width: calc(100% - 4px);
|
width: 100%;
|
||||||
margin: 2px;
|
|
||||||
border-radius: 52px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor {
|
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor {
|
||||||
height: calc(100% - 4px);
|
height: 100%;
|
||||||
margin-top: 2px;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor:nth-child(1) {
|
|
||||||
border-top-left-radius: 52px;
|
|
||||||
border-bottom-left-radius: 52px;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(3)))>.discordColorwayPreviewColor:nth-child(2) {
|
|
||||||
border-top-right-radius: 52px;
|
|
||||||
border-bottom-right-radius: 52px;
|
|
||||||
margin-right: 2px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(4)))>.discordColorwayPreviewColor:nth-child(3) {
|
.discordColorwayPreviewColorContainer:not(:has(>.discordColorwayPreviewColor:nth-child(4)))>.discordColorwayPreviewColor:nth-child(3) {
|
||||||
width: calc(100% - 4px);
|
width: 100%;
|
||||||
margin-right: 2px;
|
|
||||||
border-bottom-right-radius: 52px;
|
|
||||||
border-bottom-left-radius: 52px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ColorwaySelectorWrapper {
|
.ColorwaySelectorWrapper {
|
||||||
|
@ -138,6 +79,10 @@
|
||||||
scrollbar-width: none !important;
|
scrollbar-width: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ColorwaySelectorWrapper::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.colorwaySelectorModal {
|
.colorwaySelectorModal {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
min-width: 596px !important;
|
min-width: 596px !important;
|
||||||
|
@ -163,42 +108,23 @@
|
||||||
width: 72px;
|
width: 72px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorwayCheckIconContainer {
|
|
||||||
height: 20px;
|
|
||||||
width: 20px;
|
|
||||||
background-color: var(--brand-500);
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
border-radius: 50%;
|
|
||||||
opacity: 0;
|
|
||||||
z-index: +1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discordColorway.active .colorwayCheckIconContainer {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorwayCheckIcon {
|
|
||||||
height: 20px;
|
|
||||||
width: 20px;
|
|
||||||
color: var(--white-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorwayInfoIconContainer {
|
.colorwayInfoIconContainer {
|
||||||
height: 20px;
|
height: 22px;
|
||||||
width: 20px;
|
width: 22px;
|
||||||
background-color: var(--brand-500);
|
background-color: var(--brand-500);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: -1px;
|
||||||
left: 0;
|
left: -1px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
z-index: +1;
|
z-index: +1;
|
||||||
|
color: var(--white-500);
|
||||||
|
padding: 1px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorwayInfoIconContainer:hover {
|
.colorwayInfoIconContainer:hover {
|
||||||
background-color: var(--brand-700);
|
background-color: var(--brand-experiment-560);
|
||||||
}
|
}
|
||||||
|
|
||||||
.discordColorway:hover .colorwayInfoIconContainer {
|
.discordColorway:hover .colorwayInfoIconContainer {
|
||||||
|
@ -206,13 +132,6 @@
|
||||||
transition: .15s;
|
transition: .15s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorwayInfoIcon {
|
|
||||||
height: 20px;
|
|
||||||
width: 20px;
|
|
||||||
color: var(--white-500);
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.colorwayCreator-swatch {
|
.colorwayCreator-swatch {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -240,9 +159,7 @@
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: var(--background-secondary);
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorwayCreator-colorInput {
|
.colorwayCreator-colorInput {
|
||||||
|
@ -466,8 +383,8 @@
|
||||||
.colorwaysPreview-modal {
|
.colorwaysPreview-modal {
|
||||||
max-width: unset !important;
|
max-width: unset !important;
|
||||||
max-height: unset !important;
|
max-height: unset !important;
|
||||||
width: fit-content;
|
width: 90vw;
|
||||||
height: fit-content;
|
height: 90vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorwaysPreview-titlebar {
|
.colorwaysPreview-titlebar {
|
||||||
|
@ -652,7 +569,6 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
transition: background-color .1s linear;
|
|
||||||
font-family: var(--font-display);
|
font-family: var(--font-display);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
|
@ -1001,13 +917,28 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: var(--background-secondary);
|
}
|
||||||
|
|
||||||
|
.theme-dark .colorwaysSettings-colorwaySource {
|
||||||
|
background: var(--bg-overlay-3,var(--background-secondary));
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-light .colorwaysSettings-colorwaySource {
|
||||||
|
background: var(--bg-overlay-2,var(--background-secondary));
|
||||||
}
|
}
|
||||||
|
|
||||||
.colorwaysSettings-colorwaySource:hover {
|
.colorwaysSettings-colorwaySource:hover {
|
||||||
background-color: var(--background-secondary-alt);
|
background-color: var(--background-secondary-alt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-dark .colorwaysSettings-colorwaySource:hover {
|
||||||
|
background: var(--bg-overlay-1,var(--background-secondary-alt));
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-light .colorwaysSettings-colorwaySource:hover {
|
||||||
|
background: var(--bg-overlay-3,var(--background-secondary-alt));
|
||||||
|
}
|
||||||
|
|
||||||
.colorwaysSettings-modalRoot {
|
.colorwaysSettings-modalRoot {
|
||||||
min-width: 520px;
|
min-width: 520px;
|
||||||
}
|
}
|
||||||
|
@ -1204,3 +1135,11 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dc-warning-card {
|
||||||
|
padding: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
background-color: var(--info-warning-background);
|
||||||
|
border-color: var(--info-warning-foreground);
|
||||||
|
color: var(--info-warning-text);
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface Colorway {
|
export interface Colorway {
|
||||||
|
[key: string]: any,
|
||||||
name: string,
|
name: string,
|
||||||
"dc-import": string,
|
"dc-import": string,
|
||||||
accent: string,
|
accent: string,
|
||||||
|
@ -17,7 +18,8 @@ export interface Colorway {
|
||||||
colors?: string[],
|
colors?: string[],
|
||||||
isGradient?: boolean,
|
isGradient?: boolean,
|
||||||
sourceUrl?: string,
|
sourceUrl?: string,
|
||||||
sourceName?: string;
|
sourceName?: string,
|
||||||
|
linearGradient?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ColorPickerProps {
|
export interface ColorPickerProps {
|
||||||
|
|
Loading…
Reference in a new issue