add basic feature
This commit is contained in:
parent
431c155932
commit
8eb7f58988
9 changed files with 66 additions and 3 deletions
|
@ -41,6 +41,7 @@
|
||||||
"jshashes": "^1.0.7",
|
"jshashes": "^1.0.7",
|
||||||
"keytar": "^4.0.3",
|
"keytar": "^4.0.3",
|
||||||
"localforage": "^1.5.0",
|
"localforage": "^1.5.0",
|
||||||
|
"moment": "^2.20.1",
|
||||||
"npm": "^5.5.1",
|
"npm": "^5.5.1",
|
||||||
"qrcode.react": "^0.7.2",
|
"qrcode.react": "^0.7.2",
|
||||||
"rc-progress": "^2.0.6",
|
"rc-progress": "^2.0.6",
|
||||||
|
|
|
@ -95,6 +95,7 @@ export const SEARCH_CANCELLED = 'SEARCH_CANCELLED';
|
||||||
// Settings
|
// Settings
|
||||||
export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED';
|
export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED';
|
||||||
export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED';
|
export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED';
|
||||||
|
export const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT';
|
||||||
|
|
||||||
// User
|
// User
|
||||||
export const AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED';
|
export const AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED';
|
||||||
|
|
|
@ -11,3 +11,4 @@ export const INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled';
|
||||||
export const INSTANT_PURCHASE_MAX = 'instantPurchaseMax';
|
export const INSTANT_PURCHASE_MAX = 'instantPurchaseMax';
|
||||||
export const THEME = 'theme';
|
export const THEME = 'theme';
|
||||||
export const THEMES = 'themes';
|
export const THEMES = 'themes';
|
||||||
|
export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled';
|
||||||
|
|
|
@ -10,6 +10,7 @@ import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar } from 'redux/actions/app';
|
import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar } from 'redux/actions/app';
|
||||||
|
import { doUpdateIsNightAsync } from 'redux/actions/settings';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doDownloadLanguages } from 'redux/actions/settings';
|
import { doDownloadLanguages } from 'redux/actions/settings';
|
||||||
import { doUserEmailVerify } from 'redux/actions/user';
|
import { doUserEmailVerify } from 'redux/actions/user';
|
||||||
|
@ -97,6 +98,7 @@ document.addEventListener('click', event => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
|
app.store.dispatch(doUpdateIsNightAsync());
|
||||||
app.store.dispatch(doDownloadLanguages());
|
app.store.dispatch(doDownloadLanguages());
|
||||||
|
|
||||||
function onDaemonReady() {
|
function onDaemonReady() {
|
||||||
|
|
|
@ -28,6 +28,7 @@ const select = state => ({
|
||||||
themes: makeSelectClientSetting(settings.THEMES)(state),
|
themes: makeSelectClientSetting(settings.THEMES)(state),
|
||||||
language: selectCurrentLanguage(state),
|
language: selectCurrentLanguage(state),
|
||||||
languages: selectLanguages(state),
|
languages: selectLanguages(state),
|
||||||
|
automaticDarkModeEnabled: makeSelectClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -65,6 +65,10 @@ class SettingsPage extends React.PureComponent {
|
||||||
this.props.setClientSetting(settings.THEME, value);
|
this.props.setClientSetting(settings.THEME, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAutomaticDarkModeChange(event) {
|
||||||
|
this.props.setClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED, event.target.checked);
|
||||||
|
}
|
||||||
|
|
||||||
onInstantPurchaseEnabledChange(enabled) {
|
onInstantPurchaseEnabledChange(enabled) {
|
||||||
this.props.setClientSetting(settings.INSTANT_PURCHASE_ENABLED, enabled);
|
this.props.setClientSetting(settings.INSTANT_PURCHASE_ENABLED, enabled);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +133,7 @@ class SettingsPage extends React.PureComponent {
|
||||||
showUnavailable,
|
showUnavailable,
|
||||||
theme,
|
theme,
|
||||||
themes,
|
themes,
|
||||||
|
automaticDarkModeEnabled,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!daemonSettings || Object.keys(daemonSettings).length === 0) {
|
if (!daemonSettings || Object.keys(daemonSettings).length === 0) {
|
||||||
|
@ -317,6 +322,13 @@ class SettingsPage extends React.PureComponent {
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
<FormRow
|
||||||
|
type="checkbox"
|
||||||
|
onChange={this.onAutomaticDarkModeChange.bind(this)}
|
||||||
|
defaultChecked={automaticDarkModeEnabled}
|
||||||
|
label={__('Automatic dark mode (switch to dark theme between 9pm and 8am)')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@ import Fs from 'fs';
|
||||||
import Http from 'http';
|
import Http from 'http';
|
||||||
|
|
||||||
import Lbry from 'lbry';
|
import Lbry from 'lbry';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const UPDATE_IS_NIGHT_INTERVAL = 10 * 1000;
|
||||||
|
|
||||||
export function doFetchDaemonSettings() {
|
export function doFetchDaemonSettings() {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
|
@ -51,6 +54,29 @@ export function doGetThemes() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doUpdateIsNightAsync() {
|
||||||
|
return dispatch => {
|
||||||
|
const updateIsNightInterval = setInterval(
|
||||||
|
() => dispatch(doUpdateIsNight()),
|
||||||
|
UPDATE_IS_NIGHT_INTERVAL
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNight() {
|
||||||
|
const startNightMoment = moment('19:00', 'HH:mm');
|
||||||
|
const endNightTime = moment('8:00', 'HH:mm');
|
||||||
|
const momentNow = moment();
|
||||||
|
return momentNow.isAfter(endNightTime) && momentNow.isBefore(startNightMoment) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doUpdateIsNight() {
|
||||||
|
return {
|
||||||
|
type: ACTIONS.UPDATE_IS_NIGHT,
|
||||||
|
data: { isNight: isNight() },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function doDownloadLanguage(langFile) {
|
export function doDownloadLanguage(langFile) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
const destinationPath = `${app.i18n.directory}/${langFile}`;
|
const destinationPath = `${app.i18n.directory}/${langFile}`;
|
||||||
|
|
|
@ -23,7 +23,9 @@ const defaultState = {
|
||||||
language: getLocalStorageSetting(SETTINGS.LANGUAGE, 'en'),
|
language: getLocalStorageSetting(SETTINGS.LANGUAGE, 'en'),
|
||||||
theme: getLocalStorageSetting(SETTINGS.THEME, 'light'),
|
theme: getLocalStorageSetting(SETTINGS.THEME, 'light'),
|
||||||
themes: getLocalStorageSetting(SETTINGS.THEMES, []),
|
themes: getLocalStorageSetting(SETTINGS.THEMES, []),
|
||||||
|
automaticDarkModeEnabled: getLocalStorageSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false),
|
||||||
},
|
},
|
||||||
|
isNight: true,
|
||||||
languages: {},
|
languages: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,6 +48,11 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reducers[ACTIONS.UPDATE_IS_NIGHT] = (state, action) =>
|
||||||
|
Object.assign({}, state, {
|
||||||
|
isNight: action.data.isNight,
|
||||||
|
});
|
||||||
|
|
||||||
reducers[ACTIONS.DOWNLOAD_LANGUAGE_SUCCEEDED] = (state, action) => {
|
reducers[ACTIONS.DOWNLOAD_LANGUAGE_SUCCEEDED] = (state, action) => {
|
||||||
const languages = Object.assign({}, state.languages);
|
const languages = Object.assign({}, state.languages);
|
||||||
const { language } = action.data;
|
const { language } = action.data;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
const selectState = state => state.settings || {};
|
const selectState = state => state.settings || {};
|
||||||
|
|
||||||
|
@ -18,7 +19,18 @@ export const selectShowNsfw = makeSelectClientSetting(SETTINGS.SHOW_NSFW);
|
||||||
|
|
||||||
export const selectLanguages = createSelector(selectState, state => state.languages || {});
|
export const selectLanguages = createSelector(selectState, state => state.languages || {});
|
||||||
|
|
||||||
export const selectThemePath = createSelector(
|
export const selectTheme = makeSelectClientSetting(SETTINGS.THEME);
|
||||||
makeSelectClientSetting(SETTINGS.THEME),
|
export const selectAutomaticDarkModeEnabled = makeSelectClientSetting(
|
||||||
theme => `${staticResourcesPath}/themes/${theme || 'light'}.css`
|
SETTINGS.AUTOMATIC_DARK_MODE_ENABLED
|
||||||
|
);
|
||||||
|
export const selectIsNight = createSelector(selectState, state => state.isNight);
|
||||||
|
|
||||||
|
export const selectThemePath = createSelector(
|
||||||
|
selectTheme,
|
||||||
|
selectAutomaticDarkModeEnabled,
|
||||||
|
selectIsNight,
|
||||||
|
(theme, automaticDarkModeEnabled, isNight) => {
|
||||||
|
const dynamicTheme = automaticDarkModeEnabled && isNight ? 'dark' : theme;
|
||||||
|
return `${staticResourcesPath}/themes/${dynamicTheme || 'light'}.css`;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue