sforkowany z mirror/soapbox
Theme editor: allow saving theme
rodzic
ed12246ae4
commit
f906558dba
|
@ -103,6 +103,19 @@ const updateConfig = (configs: Record<string, any>[]) =>
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateSoapboxConfig = (data: Record<string, any>) =>
|
||||||
|
(dispatch: AppDispatch, _getState: () => RootState) => {
|
||||||
|
const params = [{
|
||||||
|
group: ':pleroma',
|
||||||
|
key: ':frontend_configurations',
|
||||||
|
value: [{
|
||||||
|
tuple: [':soapbox_fe', data],
|
||||||
|
}],
|
||||||
|
}];
|
||||||
|
|
||||||
|
return dispatch(updateConfig(params));
|
||||||
|
};
|
||||||
|
|
||||||
const fetchMastodonReports = (params: Record<string, any>) =>
|
const fetchMastodonReports = (params: Record<string, any>) =>
|
||||||
(dispatch: AppDispatch, getState: () => RootState) =>
|
(dispatch: AppDispatch, getState: () => RootState) =>
|
||||||
api(getState)
|
api(getState)
|
||||||
|
@ -585,6 +598,7 @@ export {
|
||||||
ADMIN_USERS_UNSUGGEST_FAIL,
|
ADMIN_USERS_UNSUGGEST_FAIL,
|
||||||
fetchConfig,
|
fetchConfig,
|
||||||
updateConfig,
|
updateConfig,
|
||||||
|
updateSoapboxConfig,
|
||||||
fetchReports,
|
fetchReports,
|
||||||
closeReports,
|
closeReports,
|
||||||
fetchUsers,
|
fetchUsers,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import React, { useState, useEffect, useMemo } from 'react';
|
||||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { updateConfig } from 'soapbox/actions/admin';
|
import { updateSoapboxConfig } from 'soapbox/actions/admin';
|
||||||
import { uploadMedia } from 'soapbox/actions/media';
|
import { uploadMedia } from 'soapbox/actions/media';
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
import List, { ListItem } from 'soapbox/components/list';
|
import List, { ListItem } from 'soapbox/components/list';
|
||||||
|
@ -99,18 +99,8 @@ const SoapboxConfig: React.FC = () => {
|
||||||
setJsonValid(true);
|
setJsonValid(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getParams = () => {
|
|
||||||
return [{
|
|
||||||
group: ':pleroma',
|
|
||||||
key: ':frontend_configurations',
|
|
||||||
value: [{
|
|
||||||
tuple: [':soapbox_fe', data.toJS()],
|
|
||||||
}],
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit: React.FormEventHandler = (e) => {
|
const handleSubmit: React.FormEventHandler = (e) => {
|
||||||
dispatch(updateConfig(getParams())).then(() => {
|
dispatch(updateSoapboxConfig(data.toJS())).then(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
dispatch(snackbar.success(intl.formatMessage(messages.saved)));
|
dispatch(snackbar.success(intl.formatMessage(messages.saved)));
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { updateSoapboxConfig } from 'soapbox/actions/admin';
|
||||||
|
import { getHost } from 'soapbox/actions/instance';
|
||||||
|
import snackbar from 'soapbox/actions/snackbar';
|
||||||
|
import { fetchSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
import List, { ListItem } from 'soapbox/components/list';
|
import List, { ListItem } from 'soapbox/components/list';
|
||||||
import { Column } from 'soapbox/components/ui';
|
import { Button, Column, Form, FormActions } from 'soapbox/components/ui';
|
||||||
import { useSoapboxConfig } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||||
|
|
||||||
import Palette, { ColorGroup } from './components/palette';
|
import Palette, { ColorGroup } from './components/palette';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
title: { id: 'admin.theme.title', defaultMessage: 'Theme' },
|
title: { id: 'admin.theme.title', defaultMessage: 'Theme' },
|
||||||
|
saved: { id: 'theme_editor.saved', defaultMessage: 'Theme updated!' },
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IThemeEditor {
|
interface IThemeEditor {
|
||||||
|
@ -17,12 +22,17 @@ interface IThemeEditor {
|
||||||
/** UI for editing Tailwind theme colors. */
|
/** UI for editing Tailwind theme colors. */
|
||||||
const ThemeEditor: React.FC<IThemeEditor> = () => {
|
const ThemeEditor: React.FC<IThemeEditor> = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const soapbox = useSoapboxConfig();
|
const soapbox = useSoapboxConfig();
|
||||||
|
const host = useAppSelector(state => getHost(state));
|
||||||
|
const rawConfig = useAppSelector(state => state.soapbox);
|
||||||
|
|
||||||
const [colors, setColors] = useState(soapbox.colors.toJS() as any);
|
const [colors, setColors] = useState(soapbox.colors.toJS() as any);
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
|
||||||
const updateColors = (key: string) => {
|
const updateColors = (key: string) => {
|
||||||
return (newColors: any) => {
|
return (newColors: ColorGroup) => {
|
||||||
setColors({
|
setColors({
|
||||||
...colors,
|
...colors,
|
||||||
[key]: {
|
[key]: {
|
||||||
|
@ -33,45 +43,71 @@ const ThemeEditor: React.FC<IThemeEditor> = () => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateTheme = async () => {
|
||||||
|
const params = rawConfig.set('colors', colors).toJS();
|
||||||
|
await dispatch(updateSoapboxConfig(params));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async() => {
|
||||||
|
setSubmitting(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await dispatch(fetchSoapboxConfig(host));
|
||||||
|
await updateTheme();
|
||||||
|
dispatch(snackbar.success(intl.formatMessage(messages.saved)));
|
||||||
|
setSubmitting(false);
|
||||||
|
} catch (e) {
|
||||||
|
setSubmitting(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column label={intl.formatMessage(messages.title)}>
|
<Column label={intl.formatMessage(messages.title)}>
|
||||||
<List>
|
<Form onSubmit={handleSubmit}>
|
||||||
<PaletteListItem
|
<List>
|
||||||
label='Primary'
|
<PaletteListItem
|
||||||
palette={colors.primary}
|
label='Primary'
|
||||||
onChange={updateColors('primary')}
|
palette={colors.primary}
|
||||||
/>
|
onChange={updateColors('primary')}
|
||||||
|
/>
|
||||||
|
|
||||||
<PaletteListItem
|
<PaletteListItem
|
||||||
label='Secondary'
|
label='Secondary'
|
||||||
palette={colors.secondary}
|
palette={colors.secondary}
|
||||||
onChange={updateColors('secondary')}
|
onChange={updateColors('secondary')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PaletteListItem
|
<PaletteListItem
|
||||||
label='Accent'
|
label='Accent'
|
||||||
palette={colors.accent}
|
palette={colors.accent}
|
||||||
onChange={updateColors('accent')}
|
onChange={updateColors('accent')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PaletteListItem
|
<PaletteListItem
|
||||||
label='Gray'
|
label='Gray'
|
||||||
palette={colors.gray}
|
palette={colors.gray}
|
||||||
onChange={updateColors('gray')}
|
onChange={updateColors('gray')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PaletteListItem
|
<PaletteListItem
|
||||||
label='Success'
|
label='Success'
|
||||||
palette={colors.success}
|
palette={colors.success}
|
||||||
onChange={updateColors('success')}
|
onChange={updateColors('success')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PaletteListItem
|
<PaletteListItem
|
||||||
label='Danger'
|
label='Danger'
|
||||||
palette={colors.danger}
|
palette={colors.danger}
|
||||||
onChange={updateColors('danger')}
|
onChange={updateColors('danger')}
|
||||||
/>
|
/>
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
|
<FormActions>
|
||||||
|
<Button type='submit' theme='primary' disabled={submitting}>
|
||||||
|
<FormattedMessage id='theme_editor.save' defaultMessage='Save theme' />
|
||||||
|
</Button>
|
||||||
|
</FormActions>
|
||||||
|
</Form>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Ładowanie…
Reference in New Issue