Added an export all variables mode to the CSS editor and keep these changes persistent

This commit is contained in:
WolverinDEV 2020-08-23 11:05:55 +02:00
parent 84a6e743e1
commit 1498a30bd3
4 changed files with 61 additions and 17 deletions

View file

@ -3,6 +3,7 @@ import {Stage} from "tc-loader";
import {CssEditorEvents, CssVariable} from "tc-shared/ui/modal/css-editor/Definitions"; import {CssEditorEvents, CssVariable} from "tc-shared/ui/modal/css-editor/Definitions";
import {spawnExternalModal} from "tc-shared/ui/react-elements/external-modal"; import {spawnExternalModal} from "tc-shared/ui/react-elements/external-modal";
import {Registry} from "tc-shared/events"; import {Registry} from "tc-shared/events";
import {LogCategory, logWarn} from "tc-shared/log";
interface CustomVariable { interface CustomVariable {
name: string; name: string;
@ -14,13 +15,28 @@ class CssVariableManager {
private customVariables: {[key: string]: CustomVariable} = {}; private customVariables: {[key: string]: CustomVariable} = {};
private htmlTag: HTMLStyleElement; private htmlTag: HTMLStyleElement;
constructor() { private loadLocalStorage() {
try {
const payloadString = localStorage.getItem("css-custom-variables");
if(typeof payloadString === "undefined" || !payloadString)
return;
const payload = JSON.parse(payloadString);
if(payload.version !== 1)
throw "invalid payload version";
this.customVariables = payload["customVariables"];
} catch (error) {
logWarn(LogCategory.GENERAL, tr("Failed to load custom variables: %o"), error);
}
} }
initialize() { initialize() {
this.htmlTag = document.createElement("style"); this.htmlTag = document.createElement("style");
document.body.appendChild(this.htmlTag); document.body.appendChild(this.htmlTag);
this.loadLocalStorage();
this.updateCustomVariables(false);
} }
getAllCssVariables() : CssVariable[] { getAllCssVariables() : CssVariable[] {
@ -61,7 +77,7 @@ class CssVariableManager {
const customVariable = this.customVariables[name] || (this.customVariables[name] = { name: name, value: undefined, enabled: false }); const customVariable = this.customVariables[name] || (this.customVariables[name] = { name: name, value: undefined, enabled: false });
customVariable.enabled = true; customVariable.enabled = true;
customVariable.value = value; customVariable.value = value;
this.updateCustomVariables(); this.updateCustomVariables(true);
} }
toggleCustomVariable(name: string, flag: boolean, value?: string) { toggleCustomVariable(name: string, flag: boolean, value?: string) {
@ -76,14 +92,31 @@ class CssVariableManager {
customVariable.enabled = flag; customVariable.enabled = flag;
if(flag && typeof value === "string") if(flag && typeof value === "string")
customVariable.value = value; customVariable.value = value;
this.updateCustomVariables(); this.updateCustomVariables(true);
} }
exportConfig() { exportConfig(allValues: boolean) {
return JSON.stringify({ if(allValues) {
version: 1, return JSON.stringify({
variables: this.customVariables version: 1,
}); variables: this.getAllCssVariables().map<CustomVariable>(variable => {
if(this.customVariables[variable.name]) {
return this.customVariables[variable.name];
}
return {
name: variable.name,
enabled: typeof variable.customValue !== "undefined",
value: typeof variable.customValue === "undefined" ? variable.defaultValue : variable.customValue
}
})
});
} else {
return JSON.stringify({
version: 1,
variables: this.customVariables
});
}
} }
importConfig(config: string) { importConfig(config: string) {
@ -92,12 +125,12 @@ class CssVariableManager {
throw "unsupported config version"; throw "unsupported config version";
this.customVariables = data.variables; this.customVariables = data.variables;
this.updateCustomVariables(); this.updateCustomVariables(true);
} }
reset() { reset() {
this.customVariables = {}; this.customVariables = {};
this.updateCustomVariables(); this.updateCustomVariables(true);
} }
randomize() { randomize() {
@ -109,15 +142,22 @@ class CssVariableManager {
name: e.name name: e.name
} }
}); });
this.updateCustomVariables(); this.updateCustomVariables(true);
} }
private updateCustomVariables() { private updateCustomVariables(updateConfig: boolean) {
let text = "html:root {\n"; let text = "html:root {\n";
for(const variable of Object.values(this.customVariables)) for(const variable of Object.values(this.customVariables))
text += " " + variable.name + ": " + variable.value + ";\n"; text += " " + variable.name + ": " + variable.value + ";\n";
text += "}"; text += "}";
this.htmlTag.textContent = text; this.htmlTag.textContent = text;
if(updateConfig) {
localStorage.setItem("css-custom-variables", JSON.stringify({
version: 1,
customVariables: this.customVariables
}));
}
} }
} }
let cssVariableManager: CssVariableManager; let cssVariableManager: CssVariableManager;
@ -145,9 +185,9 @@ function cssVariableEditorController(events: Registry<CssEditorEvents>) {
cssVariableManager.setVariable(event.variableName, event.value); cssVariableManager.setVariable(event.variableName, event.value);
}); });
events.on("action_export", () => { events.on("action_export", event => {
events.fire_async("notify_export_result", { events.fire_async("notify_export_result", {
config: cssVariableManager.exportConfig() config: cssVariableManager.exportConfig(event.allValues)
}); });
}); });

View file

@ -18,7 +18,7 @@ export interface CssEditorEvents {
action_reset: { }, action_reset: { },
action_randomize: {}, action_randomize: {},
action_export: {}, action_export: { allValues: boolean },
action_import: { config: string } action_import: { config: string }
query_css_variables: {}, query_css_variables: {},

View file

@ -324,7 +324,8 @@ const ControlButtons = (props: { events: Registry<CssEditorEvents> }) => {
color={"blue"} color={"blue"}
type={"normal"} type={"normal"}
className={cssStyle.button} className={cssStyle.button}
onClick={() => props.events.fire("action_export")} onClick={event => props.events.fire("action_export", { allValues: event.shiftKey })}
title={tr("Click to export the changed values, Shift click to export all values")}
><Translatable>Export</Translatable></Button> ><Translatable>Export</Translatable></Button>
<Button <Button
color={"green"} color={"green"}

View file

@ -7,10 +7,12 @@ export interface ButtonProperties {
type?: "normal" | "small" | "extra-small"; type?: "normal" | "small" | "extra-small";
className?: string; className?: string;
onClick?: () => void; onClick?: (event: React.MouseEvent) => void;
hidden?: boolean; hidden?: boolean;
disabled?: boolean; disabled?: boolean;
title?: string;
} }
export interface ButtonState { export interface ButtonState {
@ -36,6 +38,7 @@ export class Button extends ReactComponentBase<ButtonProperties, ButtonState> {
cssStyle["type-" + this.props.type] || cssStyle["type-normal"], cssStyle["type-" + this.props.type] || cssStyle["type-normal"],
this.props.className this.props.className
)} )}
title={this.props.title}
disabled={typeof this.state.disabled === "boolean" ? this.state.disabled : this.props.disabled} disabled={typeof this.state.disabled === "boolean" ? this.state.disabled : this.props.disabled}
onClick={this.props.onClick} onClick={this.props.onClick}
> >