[Appearance] factor out ThemeSelector and use it here
This commit is contained in:
parent
70f795ac8b
commit
4e0434d586
5 changed files with 153 additions and 123 deletions
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||
import Card from 'component/common/card';
|
||||
import HomepageSelector from 'component/homepageSelector';
|
||||
import SettingLanguage from 'component/settingLanguage';
|
||||
import ThemeSelector from 'component/themeSelector';
|
||||
// $FlowFixMe
|
||||
import homepages from 'homepages';
|
||||
|
||||
|
@ -27,6 +28,10 @@ export default function SettingAppearance(props: Props) {
|
|||
<div className="card__main-actions">
|
||||
<SettingLanguage />
|
||||
</div>
|
||||
|
||||
<SettingsRow title={__('Theme')}>
|
||||
<ThemeSelector />
|
||||
</SettingsRow>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
|
20
ui/component/themeSelector/index.js
Normal file
20
ui/component/themeSelector/index.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { SETTINGS } from 'lbry-redux';
|
||||
import { doSetClientSetting, doSetDarkTime } from 'redux/actions/settings';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import ThemeSelector from './view';
|
||||
|
||||
const select = (state) => ({
|
||||
currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state),
|
||||
themes: makeSelectClientSetting(SETTINGS.THEMES)(state),
|
||||
automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state),
|
||||
darkModeTimes: makeSelectClientSetting(SETTINGS.DARK_MODE_TIMES)(state),
|
||||
clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||
setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(ThemeSelector);
|
128
ui/component/themeSelector/view.jsx
Normal file
128
ui/component/themeSelector/view.jsx
Normal file
|
@ -0,0 +1,128 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { SETTINGS } from 'lbry-redux';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
||||
type SetDaemonSettingArg = boolean | string | number;
|
||||
|
||||
type DarkModeTimes = {
|
||||
from: { hour: string, min: string, formattedTime: string },
|
||||
to: { hour: string, min: string, formattedTime: string },
|
||||
};
|
||||
|
||||
type OptionTimes = {
|
||||
fromTo: string,
|
||||
time: string,
|
||||
};
|
||||
|
||||
type Props = {
|
||||
currentTheme: string,
|
||||
themes: Array<string>,
|
||||
automaticDarkModeEnabled: boolean,
|
||||
darkModeTimes: DarkModeTimes,
|
||||
clock24h: boolean,
|
||||
setClientSetting: (string, SetDaemonSettingArg) => void,
|
||||
setDarkTime: (string, {}) => void,
|
||||
};
|
||||
|
||||
export default function ThemeSelector(props: Props) {
|
||||
const {
|
||||
currentTheme,
|
||||
themes,
|
||||
automaticDarkModeEnabled,
|
||||
darkModeTimes,
|
||||
clock24h,
|
||||
setClientSetting,
|
||||
setDarkTime,
|
||||
} = props;
|
||||
|
||||
const startHours = ['18', '19', '20', '21'];
|
||||
const endHours = ['5', '6', '7', '8'];
|
||||
|
||||
function onThemeChange(event: SyntheticInputEvent<*>) {
|
||||
const { value } = event.target;
|
||||
if (value === 'dark') {
|
||||
onAutomaticDarkModeChange(false);
|
||||
}
|
||||
setClientSetting(SETTINGS.THEME, value);
|
||||
}
|
||||
|
||||
function onAutomaticDarkModeChange(value: boolean) {
|
||||
setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, value);
|
||||
}
|
||||
|
||||
function onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) {
|
||||
setDarkTime(event.target.value, options);
|
||||
}
|
||||
|
||||
function formatHour(time: string, clock24h: boolean) {
|
||||
if (clock24h) {
|
||||
return `${time}:00`;
|
||||
}
|
||||
|
||||
const now = new Date(0, 0, 0, Number(time));
|
||||
return now.toLocaleTimeString('en-US', { hour12: true, hour: '2-digit' });
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
name="theme_select"
|
||||
type="select"
|
||||
onChange={onThemeChange}
|
||||
value={currentTheme}
|
||||
disabled={automaticDarkModeEnabled}
|
||||
>
|
||||
{themes.map((theme) => (
|
||||
<option key={theme} value={theme}>
|
||||
{theme === 'light' ? __('Light') : __('Dark')}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</fieldset-section>
|
||||
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="automatic_dark_mode"
|
||||
onChange={() => onAutomaticDarkModeChange(!automaticDarkModeEnabled)}
|
||||
checked={automaticDarkModeEnabled}
|
||||
label={__('Automatic dark mode')}
|
||||
/>
|
||||
|
||||
{automaticDarkModeEnabled && (
|
||||
<fieldset-group class="fieldset-group--smushed">
|
||||
<FormField
|
||||
type="select"
|
||||
name="automatic_dark_mode_range_start"
|
||||
onChange={(value) => onChangeTime(value, { fromTo: 'from', time: 'hour' })}
|
||||
value={darkModeTimes.from.hour}
|
||||
label={__('From --[initial time]--')}
|
||||
>
|
||||
{startHours.map((time) => (
|
||||
<option key={time} value={time}>
|
||||
{formatHour(time, clock24h)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
|
||||
<FormField
|
||||
type="select"
|
||||
name="automatic_dark_mode_range_end"
|
||||
label={__('To --[final time]--')}
|
||||
onChange={(value) => onChangeTime(value, { fromTo: 'to', time: 'hour' })}
|
||||
value={darkModeTimes.to.hour}
|
||||
>
|
||||
{endHours.map((time) => (
|
||||
<option key={time} value={time}>
|
||||
{formatHour(time, clock24h)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</fieldset-group>
|
||||
)}
|
||||
</fieldset-section>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -5,7 +5,6 @@ import {
|
|||
doSetDaemonSetting,
|
||||
doClearDaemonSetting,
|
||||
doSetClientSetting,
|
||||
doSetDarkTime,
|
||||
doEnterSettingsPage,
|
||||
doExitSettingsPage,
|
||||
} from 'redux/actions/settings';
|
||||
|
@ -20,16 +19,12 @@ const select = (state) => ({
|
|||
allowAnalytics: selectAllowAnalytics(state),
|
||||
isAuthenticated: selectUserVerifiedEmail(state),
|
||||
showNsfw: selectShowMatureContent(state),
|
||||
currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state),
|
||||
themes: makeSelectClientSetting(SETTINGS.THEMES)(state),
|
||||
automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state),
|
||||
clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state),
|
||||
autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state),
|
||||
autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state),
|
||||
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
||||
floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
|
||||
hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state),
|
||||
darkModeTimes: makeSelectClientSetting(SETTINGS.DARK_MODE_TIMES)(state),
|
||||
myChannelUrls: selectMyChannelUrls(state),
|
||||
user: selectUser(state),
|
||||
});
|
||||
|
@ -40,7 +35,6 @@ const perform = (dispatch) => ({
|
|||
toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)),
|
||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
||||
setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)),
|
||||
openModal: (id, params) => dispatch(doOpenModal(id, params)),
|
||||
enterSettings: () => dispatch(doEnterSettingsPage()),
|
||||
exitSettings: () => dispatch(doExitSettingsPage()),
|
||||
|
|
|
@ -25,16 +25,6 @@ type Price = {
|
|||
|
||||
type SetDaemonSettingArg = boolean | string | number;
|
||||
|
||||
type DarkModeTimes = {
|
||||
from: { hour: string, min: string, formattedTime: string },
|
||||
to: { hour: string, min: string, formattedTime: string },
|
||||
};
|
||||
|
||||
type OptionTimes = {
|
||||
fromTo: string,
|
||||
time: string,
|
||||
};
|
||||
|
||||
type DaemonSettings = {
|
||||
download_dir: string,
|
||||
share_usage_data: boolean,
|
||||
|
@ -51,16 +41,11 @@ type Props = {
|
|||
isAuthenticated: boolean,
|
||||
instantPurchaseEnabled: boolean,
|
||||
instantPurchaseMax: Price,
|
||||
currentTheme: string,
|
||||
themes: Array<string>,
|
||||
automaticDarkModeEnabled: boolean,
|
||||
clock24h: boolean,
|
||||
autoplay: boolean,
|
||||
floatingPlayer: boolean,
|
||||
hideReposts: ?boolean,
|
||||
clearPlayingUri: () => void,
|
||||
darkModeTimes: DarkModeTimes,
|
||||
setDarkTime: (string, {}) => void,
|
||||
openModal: (string) => void,
|
||||
enterSettings: () => void,
|
||||
exitSettings: () => void,
|
||||
|
@ -69,14 +54,6 @@ type Props = {
|
|||
};
|
||||
|
||||
class SettingsPage extends React.PureComponent<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
(this: any).onThemeChange = this.onThemeChange.bind(this);
|
||||
(this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this);
|
||||
(this: any).onChangeTime = this.onChangeTime.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { enterSettings } = this.props;
|
||||
enterSettings();
|
||||
|
@ -87,42 +64,10 @@ class SettingsPage extends React.PureComponent<Props> {
|
|||
exitSettings();
|
||||
}
|
||||
|
||||
onThemeChange(event: SyntheticInputEvent<*>) {
|
||||
const { value } = event.target;
|
||||
|
||||
if (value === 'dark') {
|
||||
this.onAutomaticDarkModeChange(false);
|
||||
}
|
||||
|
||||
this.props.setClientSetting(SETTINGS.THEME, value);
|
||||
}
|
||||
|
||||
onAutomaticDarkModeChange(value: boolean) {
|
||||
this.props.setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, value);
|
||||
}
|
||||
|
||||
onClock24hChange(value: boolean) {
|
||||
this.props.setClientSetting(SETTINGS.CLOCK_24H, value);
|
||||
}
|
||||
|
||||
onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) {
|
||||
const { value } = event.target;
|
||||
|
||||
this.props.setDarkTime(value, options);
|
||||
}
|
||||
|
||||
formatHour(time: string, clock24h: boolean) {
|
||||
if (clock24h) {
|
||||
return `${time}:00`;
|
||||
}
|
||||
|
||||
const now = new Date(0, 0, 0, Number(time));
|
||||
|
||||
const hour = now.toLocaleTimeString('en-US', { hour12: true, hour: '2-digit' });
|
||||
|
||||
return hour;
|
||||
}
|
||||
|
||||
setDaemonSetting(name: string, value: ?SetDaemonSettingArg): void {
|
||||
this.props.setDaemonSetting(name, value);
|
||||
}
|
||||
|
@ -137,9 +82,6 @@ class SettingsPage extends React.PureComponent<Props> {
|
|||
allowAnalytics,
|
||||
showNsfw,
|
||||
isAuthenticated,
|
||||
currentTheme,
|
||||
themes,
|
||||
automaticDarkModeEnabled,
|
||||
clock24h,
|
||||
autoplay,
|
||||
// autoDownload,
|
||||
|
@ -149,17 +91,13 @@ class SettingsPage extends React.PureComponent<Props> {
|
|||
floatingPlayer,
|
||||
hideReposts,
|
||||
clearPlayingUri,
|
||||
darkModeTimes,
|
||||
openModal,
|
||||
myChannelUrls,
|
||||
user,
|
||||
} = this.props;
|
||||
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
||||
const startHours = ['18', '19', '20', '21'];
|
||||
const endHours = ['5', '6', '7', '8'];
|
||||
|
||||
const newStyle = true;
|
||||
|
||||
return newStyle ? (
|
||||
<Page noFooter noSideNavigation backout={{ title: __('Settings'), backLabel: __('Done') }} className="card-stack">
|
||||
<SettingAppearance />
|
||||
|
@ -219,61 +157,6 @@ class SettingsPage extends React.PureComponent<Props> {
|
|||
title={__('Appearance')}
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
name="theme_select"
|
||||
type="select"
|
||||
label={__('Theme')}
|
||||
onChange={this.onThemeChange}
|
||||
value={currentTheme}
|
||||
disabled={automaticDarkModeEnabled}
|
||||
>
|
||||
{themes.map((theme) => (
|
||||
<option key={theme} value={theme}>
|
||||
{theme === 'light' ? __('Light') : __('Dark')}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="automatic_dark_mode"
|
||||
onChange={() => this.onAutomaticDarkModeChange(!automaticDarkModeEnabled)}
|
||||
checked={automaticDarkModeEnabled}
|
||||
label={__('Automatic dark mode')}
|
||||
/>
|
||||
{automaticDarkModeEnabled && (
|
||||
<fieldset-group class="fieldset-group--smushed">
|
||||
<FormField
|
||||
type="select"
|
||||
name="automatic_dark_mode_range_start"
|
||||
onChange={(value) => this.onChangeTime(value, { fromTo: 'from', time: 'hour' })}
|
||||
value={darkModeTimes.from.hour}
|
||||
label={__('From --[initial time]--')}
|
||||
>
|
||||
{startHours.map((time) => (
|
||||
<option key={time} value={time}>
|
||||
{this.formatHour(time, clock24h)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
<FormField
|
||||
type="select"
|
||||
name="automatic_dark_mode_range_end"
|
||||
label={__('To --[final time]--')}
|
||||
onChange={(value) => this.onChangeTime(value, { fromTo: 'to', time: 'hour' })}
|
||||
value={darkModeTimes.to.hour}
|
||||
>
|
||||
{endHours.map((time) => (
|
||||
<option key={time} value={time}>
|
||||
{this.formatHour(time, clock24h)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</fieldset-group>
|
||||
)}
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
|
|
Loading…
Reference in a new issue