From 8eb7f589889285defeb11dd4889704a9ca6186fd Mon Sep 17 00:00:00 2001 From: Arrowana Date: Sun, 14 Jan 2018 20:14:15 +1100 Subject: [PATCH] add basic feature --- package.json | 1 + src/renderer/constants/action_types.js | 1 + src/renderer/constants/settings.js | 1 + src/renderer/index.js | 2 ++ src/renderer/page/settings/index.js | 1 + src/renderer/page/settings/view.jsx | 12 +++++++++++ src/renderer/redux/actions/settings.js | 26 ++++++++++++++++++++++++ src/renderer/redux/reducers/settings.js | 7 +++++++ src/renderer/redux/selectors/settings.js | 18 +++++++++++++--- 9 files changed, 66 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d0dc3f9c7..0ef710ae9 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "jshashes": "^1.0.7", "keytar": "^4.0.3", "localforage": "^1.5.0", + "moment": "^2.20.1", "npm": "^5.5.1", "qrcode.react": "^0.7.2", "rc-progress": "^2.0.6", diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index 3c828f5cb..861957d36 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -95,6 +95,7 @@ export const SEARCH_CANCELLED = 'SEARCH_CANCELLED'; // Settings export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; +export const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; // User export const AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED'; diff --git a/src/renderer/constants/settings.js b/src/renderer/constants/settings.js index dcb90ab07..9d0040412 100644 --- a/src/renderer/constants/settings.js +++ b/src/renderer/constants/settings.js @@ -11,3 +11,4 @@ export const INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; export const INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; export const THEME = 'theme'; export const THEMES = 'themes'; +export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; diff --git a/src/renderer/index.js b/src/renderer/index.js index fd6dcc1f7..1ef440174 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -10,6 +10,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar } from 'redux/actions/app'; +import { doUpdateIsNightAsync } from 'redux/actions/settings'; import { doNavigate } from 'redux/actions/navigation'; import { doDownloadLanguages } from 'redux/actions/settings'; import { doUserEmailVerify } from 'redux/actions/user'; @@ -97,6 +98,7 @@ document.addEventListener('click', event => { }); const init = () => { + app.store.dispatch(doUpdateIsNightAsync()); app.store.dispatch(doDownloadLanguages()); function onDaemonReady() { diff --git a/src/renderer/page/settings/index.js b/src/renderer/page/settings/index.js index 29d2b325c..ca277df82 100644 --- a/src/renderer/page/settings/index.js +++ b/src/renderer/page/settings/index.js @@ -28,6 +28,7 @@ const select = state => ({ themes: makeSelectClientSetting(settings.THEMES)(state), language: selectCurrentLanguage(state), languages: selectLanguages(state), + automaticDarkModeEnabled: makeSelectClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED)(state), }); const perform = dispatch => ({ diff --git a/src/renderer/page/settings/view.jsx b/src/renderer/page/settings/view.jsx index 67471841c..f3de1c2b3 100644 --- a/src/renderer/page/settings/view.jsx +++ b/src/renderer/page/settings/view.jsx @@ -65,6 +65,10 @@ class SettingsPage extends React.PureComponent { this.props.setClientSetting(settings.THEME, value); } + onAutomaticDarkModeChange(event) { + this.props.setClientSetting(settings.AUTOMATIC_DARK_MODE_ENABLED, event.target.checked); + } + onInstantPurchaseEnabledChange(enabled) { this.props.setClientSetting(settings.INSTANT_PURCHASE_ENABLED, enabled); } @@ -129,6 +133,7 @@ class SettingsPage extends React.PureComponent { showUnavailable, theme, themes, + automaticDarkModeEnabled, } = this.props; if (!daemonSettings || Object.keys(daemonSettings).length === 0) { @@ -317,6 +322,13 @@ class SettingsPage extends React.PureComponent { ))} + + diff --git a/src/renderer/redux/actions/settings.js b/src/renderer/redux/actions/settings.js index 7f0209132..841f18f82 100644 --- a/src/renderer/redux/actions/settings.js +++ b/src/renderer/redux/actions/settings.js @@ -4,6 +4,9 @@ import Fs from 'fs'; import Http from 'http'; import Lbry from 'lbry'; +import moment from 'moment'; + +const UPDATE_IS_NIGHT_INTERVAL = 10 * 1000; export function doFetchDaemonSettings() { 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) { return dispatch => { const destinationPath = `${app.i18n.directory}/${langFile}`; diff --git a/src/renderer/redux/reducers/settings.js b/src/renderer/redux/reducers/settings.js index 914404bb1..a3e6e0536 100644 --- a/src/renderer/redux/reducers/settings.js +++ b/src/renderer/redux/reducers/settings.js @@ -23,7 +23,9 @@ const defaultState = { language: getLocalStorageSetting(SETTINGS.LANGUAGE, 'en'), theme: getLocalStorageSetting(SETTINGS.THEME, 'light'), themes: getLocalStorageSetting(SETTINGS.THEMES, []), + automaticDarkModeEnabled: getLocalStorageSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false), }, + isNight: true, 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) => { const languages = Object.assign({}, state.languages); const { language } = action.data; diff --git a/src/renderer/redux/selectors/settings.js b/src/renderer/redux/selectors/settings.js index 0e2887f59..242fe4b7a 100644 --- a/src/renderer/redux/selectors/settings.js +++ b/src/renderer/redux/selectors/settings.js @@ -1,5 +1,6 @@ import * as SETTINGS from 'constants/settings'; import { createSelector } from 'reselect'; +import moment from 'moment'; 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 selectThemePath = createSelector( - makeSelectClientSetting(SETTINGS.THEME), - theme => `${staticResourcesPath}/themes/${theme || 'light'}.css` +export const selectTheme = makeSelectClientSetting(SETTINGS.THEME); +export const selectAutomaticDarkModeEnabled = makeSelectClientSetting( + 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`; + } );