Refactor the color customizing admin components
This commit is contained in:
parent
2b46bb5b6d
commit
f072819e81
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { FC, useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { Button, Col, Collapse, Row, Slider, Space } from 'antd';
|
import { Button, Col, Collapse, Row, Slider, Space } from 'antd';
|
||||||
import Paragraph from 'antd/lib/typography/Paragraph';
|
import Paragraph from 'antd/lib/typography/Paragraph';
|
||||||
@ -46,6 +46,14 @@ const componentColorVariables = [
|
|||||||
{ name: 'theme-color-components-text-on-light', description: 'Text: Dark' },
|
{ name: 'theme-color-components-text-on-light', description: 'Text: Dark' },
|
||||||
{ name: 'theme-color-background-header', description: 'Header/Footer' },
|
{ name: 'theme-color-background-header', description: 'Header/Footer' },
|
||||||
{ name: 'theme-color-components-content-background', description: 'Page Content' },
|
{ name: 'theme-color-components-content-background', description: 'Page Content' },
|
||||||
|
{
|
||||||
|
name: 'theme-color-components-video-status-bar-background',
|
||||||
|
description: 'Video Status Bar Background',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'theme-color-components-video-status-bar-foreground',
|
||||||
|
description: 'Video Status Bar Foreground',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const others = [{ name: 'theme-rounded-corners', description: 'Corner radius' }];
|
const others = [{ name: 'theme-rounded-corners', description: 'Corner radius' }];
|
||||||
@ -87,6 +95,7 @@ function ColorPicker({
|
|||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line react/function-component-definition
|
// eslint-disable-next-line react/function-component-definition
|
||||||
export default function Appearance() {
|
export default function Appearance() {
|
||||||
const serverStatusData = useContext(ServerStatusContext);
|
const serverStatusData = useContext(ServerStatusContext);
|
||||||
@ -94,7 +103,9 @@ export default function Appearance() {
|
|||||||
const { instanceDetails } = serverConfig;
|
const { instanceDetails } = serverConfig;
|
||||||
const { appearanceVariables } = instanceDetails;
|
const { appearanceVariables } = instanceDetails;
|
||||||
|
|
||||||
const [colors, setColors] = useState<Record<string, AppearanceVariable>>();
|
const [defaultValues, setDefaultValues] = useState<Record<string, AppearanceVariable>>();
|
||||||
|
const [customValues, setCustomValues] = useState<Record<string, AppearanceVariable>>();
|
||||||
|
|
||||||
const [submitStatus, setSubmitStatus] = useState<StatusState>(null);
|
const [submitStatus, setSubmitStatus] = useState<StatusState>(null);
|
||||||
|
|
||||||
let resetTimer = null;
|
let resetTimer = null;
|
||||||
@ -104,7 +115,7 @@ export default function Appearance() {
|
|||||||
clearTimeout(resetTimer);
|
clearTimeout(resetTimer);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setColorDefaults = () => {
|
const setDefaults = () => {
|
||||||
const c = {};
|
const c = {};
|
||||||
[...componentColorVariables, ...chatColorVariables, ...others].forEach(color => {
|
[...componentColorVariables, ...chatColorVariables, ...others].forEach(color => {
|
||||||
const resolvedColor = getComputedStyle(document.documentElement).getPropertyValue(
|
const resolvedColor = getComputedStyle(document.documentElement).getPropertyValue(
|
||||||
@ -112,29 +123,29 @@ export default function Appearance() {
|
|||||||
);
|
);
|
||||||
c[color.name] = { value: resolvedColor.trim(), description: color.description };
|
c[color.name] = { value: resolvedColor.trim(), description: color.description };
|
||||||
});
|
});
|
||||||
setColors(c);
|
setDefaultValues(c);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setColorDefaults();
|
setDefaults();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(appearanceVariables).length === 0) return;
|
if (Object.keys(appearanceVariables).length === 0) return;
|
||||||
|
|
||||||
const c = colors || {};
|
const c = {};
|
||||||
Object.keys(appearanceVariables).forEach(key => {
|
Object.keys(appearanceVariables).forEach(key => {
|
||||||
c[key] = {
|
c[key] = {
|
||||||
value: appearanceVariables[key],
|
value: appearanceVariables[key],
|
||||||
description: allAvailableValues[key]?.description || '',
|
description: allAvailableValues[key]?.description || '',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
setColors(c);
|
setCustomValues(c);
|
||||||
}, [appearanceVariables]);
|
}, [appearanceVariables]);
|
||||||
|
|
||||||
const updateColor = (variable: string, color: string, description: string) => {
|
const updateColor = (variable: string, color: string, description: string) => {
|
||||||
setColors({
|
setCustomValues({
|
||||||
...colors,
|
...customValues,
|
||||||
[variable]: { value: color, description },
|
[variable]: { value: color, description },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -146,7 +157,7 @@ export default function Appearance() {
|
|||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
setSubmitStatus(createInputStatus(STATUS_SUCCESS, 'Updated.'));
|
setSubmitStatus(createInputStatus(STATUS_SUCCESS, 'Updated.'));
|
||||||
resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
|
resetTimer = setTimeout(resetStates, RESET_TIMEOUT);
|
||||||
setColorDefaults();
|
setCustomValues(null);
|
||||||
},
|
},
|
||||||
onError: (message: string) => {
|
onError: (message: string) => {
|
||||||
setSubmitStatus(createInputStatus(STATUS_ERROR, message));
|
setSubmitStatus(createInputStatus(STATUS_ERROR, message));
|
||||||
@ -157,8 +168,8 @@ export default function Appearance() {
|
|||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
const c = {};
|
const c = {};
|
||||||
Object.keys(colors).forEach(color => {
|
Object.keys(customValues).forEach(color => {
|
||||||
c[color] = colors[color].value;
|
c[color] = customValues[color].value;
|
||||||
});
|
});
|
||||||
|
|
||||||
await postConfigUpdateToAPI({
|
await postConfigUpdateToAPI({
|
||||||
@ -181,7 +192,31 @@ export default function Appearance() {
|
|||||||
updateColor(variableName, `${value.toString()}px`, '');
|
updateColor(variableName, `${value.toString()}px`, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!colors) {
|
type ColorCollectionProps = {
|
||||||
|
variables: { name; description }[];
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line react/no-unstable-nested-components
|
||||||
|
const ColorCollection: FC<ColorCollectionProps> = ({ variables }) => {
|
||||||
|
const cc = variables.map(colorVar => {
|
||||||
|
const source = customValues?.[colorVar.name] ? customValues : defaultValues;
|
||||||
|
const { name, description } = colorVar;
|
||||||
|
const { value } = source[name];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ColorPicker
|
||||||
|
key={name}
|
||||||
|
value={value}
|
||||||
|
name={name}
|
||||||
|
description={description}
|
||||||
|
onChange={updateColor}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||||
|
return <>{cc}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!defaultValues) {
|
||||||
return <div>Loading...</div>;
|
return <div>Loading...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,37 +231,12 @@ export default function Appearance() {
|
|||||||
Certain sections of the interface can be customized by selecting new colors for them.
|
Certain sections of the interface can be customized by selecting new colors for them.
|
||||||
</p>
|
</p>
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
{componentColorVariables.map(colorVar => {
|
<ColorCollection variables={componentColorVariables} />
|
||||||
const { name } = colorVar;
|
|
||||||
const c = colors[name];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ColorPicker
|
|
||||||
key={name}
|
|
||||||
value={c.value}
|
|
||||||
name={name}
|
|
||||||
description={c.description}
|
|
||||||
onChange={updateColor}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Row>
|
</Row>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Panel header={<Title level={3}>Chat User Colors</Title>} key="2">
|
<Panel header={<Title level={3}>Chat User Colors</Title>} key="2">
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
{chatColorVariables.map(colorVar => {
|
<ColorCollection variables={chatColorVariables} />
|
||||||
const { name } = colorVar;
|
|
||||||
const c = colors[name];
|
|
||||||
return (
|
|
||||||
<ColorPicker
|
|
||||||
key={name}
|
|
||||||
value={c.value}
|
|
||||||
name={name}
|
|
||||||
description={c.description}
|
|
||||||
onChange={updateColor}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Row>
|
</Row>
|
||||||
</Panel>
|
</Panel>
|
||||||
|
|
||||||
@ -241,7 +251,9 @@ export default function Appearance() {
|
|||||||
onChange={v => {
|
onChange={v => {
|
||||||
onBorderRadiusChange(v);
|
onBorderRadiusChange(v);
|
||||||
}}
|
}}
|
||||||
value={Number(colors['theme-rounded-corners']?.value?.replace('px', '') || 0)}
|
value={Number(
|
||||||
|
defaultValues['theme-rounded-corners']?.value?.replace('px', '') || 0,
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={4}>
|
<Col span={4}>
|
||||||
@ -249,7 +261,7 @@ export default function Appearance() {
|
|||||||
style={{
|
style={{
|
||||||
width: '100px',
|
width: '100px',
|
||||||
height: '30px',
|
height: '30px',
|
||||||
borderRadius: `${colors['theme-rounded-corners']?.value}`,
|
borderRadius: `${defaultValues['theme-rounded-corners']?.value}`,
|
||||||
backgroundColor: 'var(--theme-color-palette-7)',
|
backgroundColor: 'var(--theme-color-palette-7)',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -9,5 +9,5 @@
|
|||||||
color: var(--theme-color-components-video-status-bar-foreground);
|
color: var(--theme-color-components-video-status-bar-foreground);
|
||||||
background-color: var(--theme-color-components-video-status-bar-background);
|
background-color: var(--theme-color-components-video-status-bar-background);
|
||||||
font-family: var(--theme-text-display-font-family);
|
font-family: var(--theme-text-display-font-family);
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user