pl-fe: dark theme preference for system theme

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2025-09-15 18:22:54 +02:00
parent f4243d9caf
commit bcc0d57641
7 changed files with 34 additions and 7 deletions

View File

@ -107,6 +107,8 @@ const messages = defineMessages({
content_type_html: { id: 'preferences.options.content_type_html', defaultMessage: 'HTML' },
content_type_wysiwyg: { id: 'preferences.options.content_type_wysiwyg', defaultMessage: 'WYSIWYG' },
brandColor: { id: 'preferences.options.brand_color', defaultMessage: 'Base color' },
dark: { id: 'theme_toggle.dark', defaultMessage: 'Dark' },
black: { id: 'theme_toggle.black', defaultMessage: 'Black' },
});
const debouncedSave = debounce((dispatch: AppDispatch) => {
@ -165,6 +167,11 @@ const Preferences = () => {
private: intl.formatMessage(messages.privacy_followers_only),
}), [settings.locale]);
const systemDarkThemePreferenceOptions = React.useMemo(() => ({
dark: intl.formatMessage(messages.dark),
black: intl.formatMessage(messages.black),
}), [settings.locale]);
const defaultContentTypeOptions = React.useMemo(() => {
const postFormats = instance.pleroma.metadata.post_formats;
@ -209,6 +216,20 @@ const Preferences = () => {
<ListItem label={<FormattedMessage id='preferences.fields.theme.display_background_gradient' defaultMessage='Display background gradient' />}>
<SettingToggle settings={settings} settingPath={['theme', 'backgroundGradient']} defaultValue onChange={onToggleChange} />
</ListItem>
{settings.themeMode === 'system' && (
<ListItem
label={<FormattedMessage id='preferences.fields.theme.dark_theme_preference_label' defaultMessage='Dark theme preference' />}
hint={<FormattedMessage id='preferences.fields.theme.dark_theme_preference_hint' defaultMessage='Select dark theme to be used when theme is set to "System"' />}
>
<SelectDropdown
className='max-w-[200px]'
items={systemDarkThemePreferenceOptions}
defaultValue={settings.theme?.systemDarkThemePreference || 'black'}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => onSelectChange(event, ['theme', 'systemDarkThemePreference'])}
/>
<SettingToggle settings={settings} settingPath={['theme', 'systemDarkThemePreference']} defaultValue onChange={onToggleChange} />
</ListItem>
)}
</List>
<HStack justifyContent='end'>

View File

@ -1,11 +1,14 @@
import { useState, useEffect } from 'react';
type SystemTheme = 'light' | 'black';
import { useSettings } from './use-settings';
import type { Theme } from './use-theme';
/** Get the system color scheme of the system. */
const useSystemTheme = (): SystemTheme => {
const useSystemTheme = (): Theme => {
const query = window.matchMedia('(prefers-color-scheme: dark)');
const [dark, setDark] = useState(query.matches);
const { theme } = useSettings();
const handleChange = (event: MediaQueryListEvent) => {
setDark(event.matches);
@ -29,7 +32,7 @@ const useSystemTheme = (): SystemTheme => {
};
}, []);
return dark ? 'black' : 'light';
return dark ? (theme?.systemDarkThemePreference || 'black') : 'light';
};
export { useSystemTheme };

View File

@ -14,4 +14,4 @@ const useTheme = (): Theme => {
return themeMode === 'system' ? systemTheme : themeMode;
};
export { useTheme };
export { useTheme, type Theme };

View File

@ -1104,7 +1104,7 @@
"list.click_to_add": "Click here to add people",
"list_adder.header_title": "Add or remove from lists",
"lists.account.add": "Add to list",
"lists.account.remove": "List members",
"lists.account.remove": "Remove from list",
"lists.delete": "Delete list",
"lists.edit": "Edit list",
"lists.edit.error": "Error updating list",
@ -1423,6 +1423,8 @@
"preferences.fields.system_emoji_font_label": "Use system emoji font",
"preferences.fields.system_font_label": "Use system's default font",
"preferences.fields.theme": "Theme",
"preferences.fields.theme.dark_theme_preference_hint": "Select dark theme to be used when theme is set to \"System\"",
"preferences.fields.theme.dark_theme_preference_label": "Dark theme preference",
"preferences.fields.theme.display_background_gradient": "Display background gradient",
"preferences.fields.theme_reset": "Reset theme",
"preferences.fields.underline_links_label": "Always underline links in posts",

View File

@ -12,7 +12,7 @@ import Search from './search';
const messages = defineMessages({
addToList: { id: 'lists.account.add', defaultMessage: 'Add to list' },
removeFromList: { id: 'lists.account.remove', defaultMessage: 'List members' },
removeFromList: { id: 'lists.account.remove', defaultMessage: 'Remove from list' },
});
interface IListMembersForm {

View File

@ -26,7 +26,7 @@ const ListEditorModal: React.FC<BaseModalProps & ListEditorModalProps> = ({ list
return (
<Modal
title={tab === 'info' ? <FormattedMessage id='lists.edit' defaultMessage='Edit list' /> : <FormattedMessage id='lists.manage_members' defaultMessage='Manage list memebrs' />}
title={tab === 'info' ? <FormattedMessage id='lists.edit' defaultMessage='Edit list' /> : <FormattedMessage id='lists.manage_members' defaultMessage='Manage list members' />}
onClose={onClickClose}
onBack={tab === 'members' ? () => setTab('info') : undefined}
>

View File

@ -61,6 +61,7 @@ const settingsSchema = v.object({
colors: v.optional(v.any()),
interfaceSize: v.fallback(v.picklist(['sm', 'md', 'lg', 'xl']), 'md'),
backgroundGradient: v.optional(v.boolean(), true),
systemDarkThemePreference: v.fallback(v.picklist(['dark', 'black']), 'black'),
}), undefined),
systemFont: v.fallback(v.boolean(), false),