Merge branch 'theme-toggle' into 'develop'

Light/dark theme toggle in top navbar

See merge request soapbox-pub/soapbox-fe!97
This commit is contained in:
Alex Gleason 2020-07-11 20:40:26 +00:00
commit 49a3211777
3 changed files with 32 additions and 13 deletions

View file

@ -79,8 +79,6 @@ const languages = {
const messages = defineMessages({
heading: { id: 'column.preferences', defaultMessage: 'Preferences' },
themeLight: { id: 'preferences.options.theme_light', defaultMessage: 'Light' },
themeDark: { id: 'preferences.options.theme_dark', defaultMessage: 'Dark' },
});
const mapStateToProps = state => ({
@ -114,15 +112,6 @@ class Preferences extends ImmutablePureComponent {
return (
<Column icon='cog' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<SimpleForm>
<FieldsGroup>
<SelectDropdown
label={<FormattedMessage id='preferences.fields.theme_label' defaultMessage='Theme' />}
items={{ light: intl.formatMessage(messages.themeLight), dark: intl.formatMessage(messages.themeDark) }}
defaultValue={settings.get('themeMode')}
onChange={this.onSelectChange(['themeMode'])}
/>
</FieldsGroup>
<FieldsGroup>
<SelectDropdown
label={<FormattedMessage id='preferences.fields.language_label' defaultMessage='Language' />}

View file

@ -13,9 +13,12 @@ import ActionBar from 'soapbox/features/compose/components/action_bar';
import { openModal } from '../../../actions/modal';
import { openSidebar } from '../../../actions/sidebar';
import Icon from '../../../components/icon';
import { changeSetting } from 'soapbox/actions/settings';
const messages = defineMessages({
post: { id: 'tabs_bar.post', defaultMessage: 'Post' },
switchToLight: { id: 'tabs_bar.theme_toggle_light', defaultMessage: 'Switch to light theme' },
switchToDark: { id: 'tabs_bar.theme_toggle_dark', defaultMessage: 'Switch to dark theme' },
});
@withRouter
@ -26,8 +29,10 @@ class TabsBar extends React.PureComponent {
history: PropTypes.object.isRequired,
onOpenCompose: PropTypes.func,
onOpenSidebar: PropTypes.func.isRequired,
toggleTheme: PropTypes.func,
logo: PropTypes.string,
account: ImmutablePropTypes.map,
settings: ImmutablePropTypes.map,
}
state = {
@ -102,6 +107,16 @@ class TabsBar extends React.PureComponent {
}));
}
getNewThemeValue() {
if (this.props.settings.get('themeMode') === 'light') return 'dark';
return 'light';
}
handleToggleTheme = () => {
this.props.toggleTheme(this.getNewThemeValue());
}
handleScroll = throttle(() => {
if (this.window) {
const { pageYOffset, innerWidth } = this.window;
@ -124,7 +139,7 @@ class TabsBar extends React.PureComponent {
});
render() {
const { account, onOpenCompose, onOpenSidebar, intl } = this.props;
const { account, onOpenCompose, onOpenSidebar, intl, settings } = this.props;
const { collapsed } = this.state;
const classes = classNames('tabs-bar', {
@ -143,6 +158,9 @@ class TabsBar extends React.PureComponent {
</div>
{ account &&
<div className='flex'>
<button className='tabs-bar__button-theme-toggle button' onClick={this.handleToggleTheme} aria-label={settings.get('themeMode') === 'light' ? intl.formatMessage(messages.switchToDark) : intl.formatMessage(messages.switchToLight)}>
<Icon id={settings.get('themeMode') === 'light' ? 'sun' : 'moon'} />
</button>
<div className='tabs-bar__profile'>
<Avatar account={account} />
<button className='tabs-bar__sidebar-btn' onClick={onOpenSidebar} />
@ -177,6 +195,7 @@ const mapStateToProps = state => {
return {
account: state.getIn(['accounts', me]),
logo: state.getIn(['soapbox', 'logo']),
settings: state.get('settings'),
};
};
@ -187,6 +206,9 @@ const mapDispatchToProps = (dispatch) => ({
onOpenSidebar() {
dispatch(openSidebar());
},
toggleTheme(setting) {
dispatch(changeSetting(['themeMode'], setting));
},
});
export default injectIntl(

View file

@ -55,7 +55,7 @@
&__profile {
position: relative;
overflow: hidden;
margin: 0 0 0 20px;
margin: 0 0 0 10px;
height: 34px;
width: 34px;
@ -111,6 +111,14 @@
}
}
&__button-theme-toggle {
margin-left: 10px;
padding: 0 10px;
font-size: 20px;
.fa { margin-right: 0; }
}
&__button-compose {
display: block;
@media screen and (max-width: $nav-breakpoint-3) {display: none;}