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