pl-fe: allow user to change ui color
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
parent
a535b80546
commit
156a0b0826
6 changed files with 41 additions and 4 deletions
|
@ -17,13 +17,16 @@ const FE_NAME = 'pl_fe';
|
|||
type SettingOpts = {
|
||||
/** Whether to display an alert when settings are saved. */
|
||||
showAlert?: boolean;
|
||||
save?: boolean;
|
||||
}
|
||||
|
||||
const saveSuccessMessage = defineMessage({ id: 'settings.save.success', defaultMessage: 'Your preferences have been saved!' });
|
||||
|
||||
const changeSetting = (path: string[], value: any, opts?: SettingOpts) => {
|
||||
useSettingsStore.getState().changeSetting(path, value);
|
||||
return saveSettings(opts);
|
||||
|
||||
if (opts?.save !== false) return saveSettings(opts);
|
||||
return () => {};
|
||||
};
|
||||
|
||||
const saveSettings = (opts?: SettingOpts) =>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import debounce from 'lodash/debounce';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { changeSetting } from 'pl-fe/actions/settings';
|
||||
import { changeSetting, saveSettings } from 'pl-fe/actions/settings';
|
||||
import List, { ListItem } from 'pl-fe/components/list';
|
||||
import Form from 'pl-fe/components/ui/form';
|
||||
import { Mutliselect, SelectDropdown } from 'pl-fe/features/forms';
|
||||
|
@ -9,10 +10,15 @@ import SettingToggle from 'pl-fe/features/notifications/components/setting-toggl
|
|||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||
import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config';
|
||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||
import colors from 'pl-fe/utils/colors';
|
||||
|
||||
import { PaletteListItem } from '../theme-editor';
|
||||
import ThemeToggle from '../ui/components/theme-toggle';
|
||||
|
||||
import type { AppDispatch } from 'pl-fe/store';
|
||||
|
||||
const languages = {
|
||||
en: 'English',
|
||||
ar: 'العربية',
|
||||
|
@ -91,13 +97,19 @@ const messages = defineMessages({
|
|||
content_type_plaintext: { id: 'preferences.options.content_type_plaintext', defaultMessage: 'Plain text' },
|
||||
content_type_markdown: { id: 'preferences.options.content_type_markdown', defaultMessage: 'Markdown' },
|
||||
content_type_html: { id: 'preferences.options.content_type_html', defaultMessage: 'HTML' },
|
||||
brandColor: { id: 'preferences.options.brand_color', defaultMessage: 'Base color' },
|
||||
});
|
||||
|
||||
const debouncedSave = debounce((dispatch: AppDispatch) => {
|
||||
dispatch(saveSettings({ showAlert: true }));
|
||||
}, 1000);
|
||||
|
||||
const Preferences = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const settings = useSettings();
|
||||
const plFeConfig = usePlFeConfig();
|
||||
const instance = useInstance();
|
||||
|
||||
const onSelectChange = (event: React.ChangeEvent<HTMLSelectElement>, path: string[]) => {
|
||||
|
@ -109,7 +121,14 @@ const Preferences = () => {
|
|||
};
|
||||
|
||||
const onToggleChange = (key: string[], checked: boolean) => {
|
||||
dispatch(changeSetting(key, checked, { showAlert: true }));
|
||||
dispatch(changeSetting(key, checked));
|
||||
};
|
||||
|
||||
const onBrandColorChange = (brandColor: string) => {
|
||||
if (!settings.theme?.brandColor && brandColor === (plFeConfig.brandColor || '#d80482')) return;
|
||||
|
||||
dispatch(changeSetting(['theme', 'brandColor'], brandColor, { showAlert: true, save: false }));
|
||||
debouncedSave(dispatch);
|
||||
};
|
||||
|
||||
const displayMediaOptions = React.useMemo(() => ({
|
||||
|
@ -152,7 +171,14 @@ const Preferences = () => {
|
|||
<ListItem label={<FormattedMessage id='preferences.fields.theme' defaultMessage='Theme' />}>
|
||||
<ThemeToggle />
|
||||
</ListItem>
|
||||
<PaletteListItem
|
||||
label={intl.formatMessage(messages.brandColor)}
|
||||
palette={colors(settings.theme?.brandColor || plFeConfig.brandColor || '#d80482')}
|
||||
onChange={(palette) => onBrandColorChange(palette['500'])}
|
||||
/>
|
||||
</List>
|
||||
|
||||
<List>
|
||||
<ListItem label={<FormattedMessage id='preferences.fields.language_label' defaultMessage='Display language' />}>
|
||||
<SelectDropdown
|
||||
className='max-w-[200px]'
|
||||
|
|
|
@ -283,4 +283,4 @@ const ColorListItem: React.FC<IColorListItem> = ({ label, value, onChange }) =>
|
|||
);
|
||||
};
|
||||
|
||||
export { ThemeEditor as default };
|
||||
export { ThemeEditor as default, PaletteListItem };
|
||||
|
|
|
@ -1266,6 +1266,7 @@
|
|||
"preferences.fields.wrench_label": "Display wrench reaction button",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.brand_color": "Base color",
|
||||
"preferences.options.content_type_html": "HTML",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_mfm": "MFM",
|
||||
|
|
|
@ -38,6 +38,12 @@ const settingsSchema = v.object({
|
|||
knownLanguages: v.fallback(v.array(v.string()), []),
|
||||
showWrenchButton: v.fallback(v.boolean(), false),
|
||||
|
||||
theme: v.fallback(v.optional(v.object({
|
||||
brandColor: v.fallback(v.string(), ''),
|
||||
accentColor: v.fallback(v.string(), ''),
|
||||
colors: v.any(),
|
||||
})), undefined),
|
||||
|
||||
systemFont: v.fallback(v.boolean(), false),
|
||||
demetricator: v.fallback(v.boolean(), false),
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ const useSettingsStore = create<State>()(mutative((set) => ({
|
|||
}),
|
||||
|
||||
changeSetting: (path: string[], value: any) => set((state: State) => {
|
||||
state.userSettings.saved = false;
|
||||
changeSetting(state.userSettings, path, value);
|
||||
|
||||
mergeSettings(state);
|
||||
|
|
Loading…
Reference in a new issue