0

Refactor the color customizing admin components

This commit is contained in:
Gabe Kangas 2023-01-18 19:05:27 -08:00
parent 2b46bb5b6d
commit f072819e81
No known key found for this signature in database
GPG Key ID: 4345B2060657F330
2 changed files with 55 additions and 43 deletions

View File

@ -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)',
}} }}
/> />

View File

@ -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;
} }