kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Merge branch 'next-theme-toggle' into 'next'
Next: theme toggle See merge request soapbox-pub/soapbox-fe!1147virtualized-window
commit
2e7f6805b5
|
@ -6,6 +6,7 @@ import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { Avatar, Button, Icon } from 'soapbox/components/ui';
|
import { Avatar, Button, Icon } from 'soapbox/components/ui';
|
||||||
import Search from 'soapbox/features/compose/components/search';
|
import Search from 'soapbox/features/compose/components/search';
|
||||||
|
import ThemeToggle from 'soapbox/features/ui/components/theme_toggle';
|
||||||
import { useOwnAccount, useSoapboxConfig, useSettings } from 'soapbox/hooks';
|
import { useOwnAccount, useSoapboxConfig, useSettings } from 'soapbox/hooks';
|
||||||
|
|
||||||
import { openSidebar } from '../../../actions/sidebar';
|
import { openSidebar } from '../../../actions/sidebar';
|
||||||
|
@ -67,6 +68,10 @@ const Navbar = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='absolute inset-y-0 right-0 flex items-center pr-2 lg:static lg:inset-auto lg:ml-6 lg:pr-0 space-x-3'>
|
<div className='absolute inset-y-0 right-0 flex items-center pr-2 lg:static lg:inset-auto lg:ml-6 lg:pr-0 space-x-3'>
|
||||||
|
{settings.get('isDeveloper') && (
|
||||||
|
<ThemeToggle />
|
||||||
|
)}
|
||||||
|
|
||||||
{account ? (
|
{account ? (
|
||||||
<div className='hidden relative lg:flex items-center'>
|
<div className='hidden relative lg:flex items-center'>
|
||||||
<ProfileDropdown account={account}>
|
<ProfileDropdown account={account}>
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
import { defineMessages } from 'react-intl';
|
|
||||||
import Toggle from 'react-toggle';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
switchToLight: { id: 'tabs_bar.theme_toggle_light', defaultMessage: 'Switch to light theme' },
|
|
||||||
switchToDark: { id: 'tabs_bar.theme_toggle_dark', defaultMessage: 'Switch to dark theme' },
|
|
||||||
});
|
|
||||||
|
|
||||||
export default class ThemeToggle extends ImmutablePureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
themeMode: PropTypes.string.isRequired,
|
|
||||||
onToggle: PropTypes.func.isRequired,
|
|
||||||
showLabel: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleToggleTheme = () => {
|
|
||||||
this.props.onToggle(this.props.themeMode === 'light' ? 'dark' : 'light');
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { intl, themeMode, showLabel } = this.props;
|
|
||||||
const id ='theme-toggle';
|
|
||||||
const label = intl.formatMessage(themeMode === 'light' ? messages.switchToDark : messages.switchToLight);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='theme-toggle'>
|
|
||||||
<div className='setting-toggle' aria-label={label}>
|
|
||||||
<Toggle
|
|
||||||
id={id}
|
|
||||||
checked={themeMode === 'light'}
|
|
||||||
onChange={this.handleToggleTheme}
|
|
||||||
onKeyDown={this.onKeyDown}
|
|
||||||
/>
|
|
||||||
{showLabel && (<label htmlFor={id} className='setting-toggle__label'>{label}</label>)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import Toggle from 'react-toggle';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
import { changeSetting } from 'soapbox/actions/settings';
|
||||||
|
import { Icon } from 'soapbox/components/ui';
|
||||||
|
import { useSettings } from 'soapbox/hooks';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
switchToLight: { id: 'tabs_bar.theme_toggle_light', defaultMessage: 'Switch to light theme' },
|
||||||
|
switchToDark: { id: 'tabs_bar.theme_toggle_dark', defaultMessage: 'Switch to dark theme' },
|
||||||
|
});
|
||||||
|
|
||||||
|
interface IThemeToggle {
|
||||||
|
showLabel?: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
function ThemeToggle({ showLabel }: IThemeToggle) {
|
||||||
|
const intl = useIntl();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const themeMode = useSettings().get('themeMode');
|
||||||
|
|
||||||
|
const id = uuidv4();
|
||||||
|
const label = intl.formatMessage(themeMode === 'light' ? messages.switchToDark : messages.switchToLight);
|
||||||
|
|
||||||
|
const onToggle = () => {
|
||||||
|
const setting = themeMode === 'light' ? 'dark' : 'light';
|
||||||
|
dispatch(changeSetting(['themeMode'], setting));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='theme-toggle'>
|
||||||
|
<div className='setting-toggle' aria-label={label}>
|
||||||
|
<Toggle
|
||||||
|
id={id}
|
||||||
|
checked={themeMode === 'light'}
|
||||||
|
icons={{
|
||||||
|
checked: <Icon src={require('@tabler/icons/icons/sun.svg')} />,
|
||||||
|
unchecked: <Icon src={require('@tabler/icons/icons/moon.svg')} />,
|
||||||
|
}}
|
||||||
|
onChange={onToggle}
|
||||||
|
/>
|
||||||
|
{showLabel && (<label htmlFor={id} className='setting-toggle__label'>{label}</label>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ThemeToggle;
|
|
@ -1,20 +0,0 @@
|
||||||
import { injectIntl } from 'react-intl';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { changeSetting, getSettings } from 'soapbox/actions/settings';
|
|
||||||
|
|
||||||
import ThemeToggle from './theme_toggle';
|
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
|
||||||
return {
|
|
||||||
themeMode: getSettings(state).get('themeMode'),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
|
||||||
onToggle(setting) {
|
|
||||||
dispatch(changeSetting(['themeMode'], setting));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ThemeToggle));
|
|
|
@ -72,6 +72,7 @@
|
||||||
"@types/lodash": "^4.14.180",
|
"@types/lodash": "^4.14.180",
|
||||||
"@types/react-helmet": "^6.1.5",
|
"@types/react-helmet": "^6.1.5",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
|
"@types/react-toggle": "^4.0.3",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"array-includes": "^3.0.3",
|
"array-includes": "^3.0.3",
|
||||||
"autoprefixer": "^10.4.2",
|
"autoprefixer": "^10.4.2",
|
||||||
|
|
|
@ -2129,6 +2129,13 @@
|
||||||
"@types/history" "^4.7.11"
|
"@types/history" "^4.7.11"
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-toggle@^4.0.3":
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-toggle/-/react-toggle-4.0.3.tgz#8db98ac8d2c5e8c03c2d3a42027555c1cd2289da"
|
||||||
|
integrity sha512-57QdMWeeQdRjM2/p+udgYerxUbSkmeUIW18kwUttcci6GHkgxoqCsDZfRtsCsAHcvvM5VBQdtDUEgLWo2e87mA==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@17":
|
"@types/react@*", "@types/react@17":
|
||||||
version "17.0.21"
|
version "17.0.21"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.21.tgz#069c43177cd419afaab5ce26bb4e9056549f7ea6"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.21.tgz#069c43177cd419afaab5ce26bb4e9056549f7ea6"
|
||||||
|
|
Ładowanie…
Reference in New Issue