[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 Card from 'component/common/card';
|
||||||
import HomepageSelector from 'component/homepageSelector';
|
import HomepageSelector from 'component/homepageSelector';
|
||||||
import SettingLanguage from 'component/settingLanguage';
|
import SettingLanguage from 'component/settingLanguage';
|
||||||
|
import ThemeSelector from 'component/themeSelector';
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
import homepages from 'homepages';
|
import homepages from 'homepages';
|
||||||
|
|
||||||
|
@ -27,6 +28,10 @@ export default function SettingAppearance(props: Props) {
|
||||||
<div className="card__main-actions">
|
<div className="card__main-actions">
|
||||||
<SettingLanguage />
|
<SettingLanguage />
|
||||||
</div>
|
</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,
|
doSetDaemonSetting,
|
||||||
doClearDaemonSetting,
|
doClearDaemonSetting,
|
||||||
doSetClientSetting,
|
doSetClientSetting,
|
||||||
doSetDarkTime,
|
|
||||||
doEnterSettingsPage,
|
doEnterSettingsPage,
|
||||||
doExitSettingsPage,
|
doExitSettingsPage,
|
||||||
} from 'redux/actions/settings';
|
} from 'redux/actions/settings';
|
||||||
|
@ -20,16 +19,12 @@ const select = (state) => ({
|
||||||
allowAnalytics: selectAllowAnalytics(state),
|
allowAnalytics: selectAllowAnalytics(state),
|
||||||
isAuthenticated: selectUserVerifiedEmail(state),
|
isAuthenticated: selectUserVerifiedEmail(state),
|
||||||
showNsfw: selectShowMatureContent(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),
|
clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state),
|
||||||
autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state),
|
autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state),
|
||||||
autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state),
|
autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state),
|
||||||
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
||||||
floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
|
floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
|
||||||
hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state),
|
hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state),
|
||||||
darkModeTimes: makeSelectClientSetting(SETTINGS.DARK_MODE_TIMES)(state),
|
|
||||||
myChannelUrls: selectMyChannelUrls(state),
|
myChannelUrls: selectMyChannelUrls(state),
|
||||||
user: selectUser(state),
|
user: selectUser(state),
|
||||||
});
|
});
|
||||||
|
@ -40,7 +35,6 @@ const perform = (dispatch) => ({
|
||||||
toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)),
|
toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)),
|
||||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||||
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
||||||
setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)),
|
|
||||||
openModal: (id, params) => dispatch(doOpenModal(id, params)),
|
openModal: (id, params) => dispatch(doOpenModal(id, params)),
|
||||||
enterSettings: () => dispatch(doEnterSettingsPage()),
|
enterSettings: () => dispatch(doEnterSettingsPage()),
|
||||||
exitSettings: () => dispatch(doExitSettingsPage()),
|
exitSettings: () => dispatch(doExitSettingsPage()),
|
||||||
|
|
|
@ -25,16 +25,6 @@ type Price = {
|
||||||
|
|
||||||
type SetDaemonSettingArg = boolean | string | number;
|
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 = {
|
type DaemonSettings = {
|
||||||
download_dir: string,
|
download_dir: string,
|
||||||
share_usage_data: boolean,
|
share_usage_data: boolean,
|
||||||
|
@ -51,16 +41,11 @@ type Props = {
|
||||||
isAuthenticated: boolean,
|
isAuthenticated: boolean,
|
||||||
instantPurchaseEnabled: boolean,
|
instantPurchaseEnabled: boolean,
|
||||||
instantPurchaseMax: Price,
|
instantPurchaseMax: Price,
|
||||||
currentTheme: string,
|
|
||||||
themes: Array<string>,
|
|
||||||
automaticDarkModeEnabled: boolean,
|
|
||||||
clock24h: boolean,
|
clock24h: boolean,
|
||||||
autoplay: boolean,
|
autoplay: boolean,
|
||||||
floatingPlayer: boolean,
|
floatingPlayer: boolean,
|
||||||
hideReposts: ?boolean,
|
hideReposts: ?boolean,
|
||||||
clearPlayingUri: () => void,
|
clearPlayingUri: () => void,
|
||||||
darkModeTimes: DarkModeTimes,
|
|
||||||
setDarkTime: (string, {}) => void,
|
|
||||||
openModal: (string) => void,
|
openModal: (string) => void,
|
||||||
enterSettings: () => void,
|
enterSettings: () => void,
|
||||||
exitSettings: () => void,
|
exitSettings: () => void,
|
||||||
|
@ -69,14 +54,6 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class SettingsPage extends React.PureComponent<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() {
|
componentDidMount() {
|
||||||
const { enterSettings } = this.props;
|
const { enterSettings } = this.props;
|
||||||
enterSettings();
|
enterSettings();
|
||||||
|
@ -87,42 +64,10 @@ class SettingsPage extends React.PureComponent<Props> {
|
||||||
exitSettings();
|
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) {
|
onClock24hChange(value: boolean) {
|
||||||
this.props.setClientSetting(SETTINGS.CLOCK_24H, value);
|
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 {
|
setDaemonSetting(name: string, value: ?SetDaemonSettingArg): void {
|
||||||
this.props.setDaemonSetting(name, value);
|
this.props.setDaemonSetting(name, value);
|
||||||
}
|
}
|
||||||
|
@ -137,9 +82,6 @@ class SettingsPage extends React.PureComponent<Props> {
|
||||||
allowAnalytics,
|
allowAnalytics,
|
||||||
showNsfw,
|
showNsfw,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
currentTheme,
|
|
||||||
themes,
|
|
||||||
automaticDarkModeEnabled,
|
|
||||||
clock24h,
|
clock24h,
|
||||||
autoplay,
|
autoplay,
|
||||||
// autoDownload,
|
// autoDownload,
|
||||||
|
@ -149,17 +91,13 @@ class SettingsPage extends React.PureComponent<Props> {
|
||||||
floatingPlayer,
|
floatingPlayer,
|
||||||
hideReposts,
|
hideReposts,
|
||||||
clearPlayingUri,
|
clearPlayingUri,
|
||||||
darkModeTimes,
|
|
||||||
openModal,
|
openModal,
|
||||||
myChannelUrls,
|
myChannelUrls,
|
||||||
user,
|
user,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
||||||
const startHours = ['18', '19', '20', '21'];
|
|
||||||
const endHours = ['5', '6', '7', '8'];
|
|
||||||
|
|
||||||
const newStyle = true;
|
const newStyle = true;
|
||||||
|
|
||||||
return newStyle ? (
|
return newStyle ? (
|
||||||
<Page noFooter noSideNavigation backout={{ title: __('Settings'), backLabel: __('Done') }} className="card-stack">
|
<Page noFooter noSideNavigation backout={{ title: __('Settings'), backLabel: __('Done') }} className="card-stack">
|
||||||
<SettingAppearance />
|
<SettingAppearance />
|
||||||
|
@ -219,61 +157,6 @@ class SettingsPage extends React.PureComponent<Props> {
|
||||||
title={__('Appearance')}
|
title={__('Appearance')}
|
||||||
actions={
|
actions={
|
||||||
<React.Fragment>
|
<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>
|
<fieldset-section>
|
||||||
<FormField
|
<FormField
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|
Loading…
Reference in a new issue