Skip to content

Commit 4ea044a

Browse files
committed
feat(App): Lay groundwork for general themeing support
1 parent 0440c74 commit 4ea044a

11 files changed

Lines changed: 396 additions & 49 deletions

File tree

gulpfile.babel.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@ import { exec } from 'child_process';
77
import dotenv from 'dotenv';
88
import sassVariables from 'gulp-sass-variables';
99
import { removeSync } from 'fs-extra';
10+
import kebabCase from 'kebab-case';
11+
import hexRgb from 'hex-rgb';
1012

1113
import config from './package.json';
1214

15+
import * as rawStyleConfig from './src/theme/default/legacy.js';
16+
1317
dotenv.config();
1418

19+
const styleConfig = Object.keys(rawStyleConfig).map((key) => {
20+
const isHex = /^#[0-9A-F]{6}$/i.test(rawStyleConfig[key]);
21+
return ({ [`$raw_${kebabCase(key)}`]: isHex ? hexRgb(rawStyleConfig[key], { format: 'array' }).splice(0, 3).join(',') : rawStyleConfig[key] });
22+
});
23+
1524
const paths = {
1625
src: 'src',
1726
dest: 'build',
@@ -83,9 +92,9 @@ export function html() {
8392

8493
export function styles() {
8594
return gulp.src(paths.styles.src)
86-
.pipe(sassVariables({
95+
.pipe(sassVariables(Object.assign({
8796
$env: process.env.NODE_ENV === 'development' ? 'development' : 'production',
88-
}))
97+
}, ...styleConfig)))
8998
.pipe(sass({
9099
includePaths: [
91100
'./node_modules',

package-lock.json

Lines changed: 165 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"private": true,
1212
"scripts": {
1313
"prestart": "npm run rebuild",
14-
"start": "DEBUG=Franz:* electron ./build",
14+
"start": "electron ./build",
1515
"start:local": "cross-env LOCAL_API=1 npm start",
1616
"start:live": "cross-env LIVE_API=1 npm start",
1717
"dev": "cross-env NODE_ENV=development gulp dev",
@@ -67,6 +67,7 @@
6767
"react-dropzone": "^4.2.1",
6868
"react-electron-web-view": "^2.0.1",
6969
"react-intl": "^2.3.0",
70+
"react-jss": "8.6.1",
7071
"react-loader": "^2.4.0",
7172
"react-router": "^3.0.2",
7273
"react-router-transition": "^0.1.1",
@@ -108,7 +109,9 @@
108109
"gulp-sass": "^4.0.2",
109110
"gulp-sass-variables": "^1.1.1",
110111
"gulp-server-livereload": "^1.9.2",
112+
"hex-rgb": "3.0.0",
111113
"husky": "^1.1.4",
114+
"kebab-case": "1.0.0",
112115
"node-sass": "^4.7.2",
113116
"prettier": "1.15.2"
114117
},

src/components/settings/navigation/SettingsNavigation.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ const messages = defineMessages({
3232
},
3333
});
3434

35-
@inject('stores') @observer
36-
export default class SettingsNavigation extends Component {
35+
export default @inject('stores') @observer class SettingsNavigation extends Component {
3736
static propTypes = {
3837
serviceCount: PropTypes.number.isRequired,
3938
};

src/containers/layout/AppLayoutContainer.js

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import { inject, observer } from 'mobx-react';
4+
import { ThemeProvider } from 'react-jss';
45

56
import AppStore from '../../stores/AppStore';
67
import RecipesStore from '../../stores/RecipesStore';
@@ -109,26 +110,28 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
109110
);
110111

111112
return (
112-
<AppLayout
113-
isFullScreen={app.isFullScreen}
114-
isOnline={app.isOnline}
115-
showServicesUpdatedInfoBar={ui.showServicesUpdatedInfoBar}
116-
appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED}
117-
sidebar={sidebar}
118-
services={servicesContainer}
119-
news={news.latest}
120-
removeNewsItem={hide}
121-
reloadServicesAfterUpdate={reloadUpdatedServices}
122-
installAppUpdate={installUpdate}
123-
globalError={globalError.error}
124-
showRequiredRequestsError={requests.showRequiredRequestsError}
125-
areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful}
126-
retryRequiredRequests={retryRequiredRequests}
127-
areRequiredRequestsLoading={requests.areRequiredRequestsLoading}
128-
darkMode={settings.all.app.darkMode}
129-
>
130-
{React.Children.count(children) > 0 ? children : null}
131-
</AppLayout>
113+
<ThemeProvider theme={ui.theme}>
114+
<AppLayout
115+
isFullScreen={app.isFullScreen}
116+
isOnline={app.isOnline}
117+
showServicesUpdatedInfoBar={ui.showServicesUpdatedInfoBar}
118+
appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED}
119+
sidebar={sidebar}
120+
services={servicesContainer}
121+
news={news.latest}
122+
removeNewsItem={hide}
123+
reloadServicesAfterUpdate={reloadUpdatedServices}
124+
installAppUpdate={installUpdate}
125+
globalError={globalError.error}
126+
showRequiredRequestsError={requests.showRequiredRequestsError}
127+
areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful}
128+
retryRequiredRequests={retryRequiredRequests}
129+
areRequiredRequestsLoading={requests.areRequiredRequestsLoading}
130+
darkMode={settings.all.app.darkMode}
131+
>
132+
{React.Children.count(children) > 0 ? children : null}
133+
</AppLayout>
134+
</ThemeProvider>
132135
);
133136
}
134137
}

src/stores/UIStore.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { action, observable, computed } from 'mobx';
22

33
import Store from './lib/Store';
4+
import * as themeDefault from '../theme/default';
5+
import * as themeDark from '../theme/dark';
46

57
export default class UIStore extends Store {
68
@observable showServicesUpdatedInfoBar = false;
@@ -20,6 +22,14 @@ export default class UIStore extends Store {
2022
return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.isAppMuted;
2123
}
2224

25+
@computed get theme() {
26+
if (this.stores.settings.all.app.darkMode) {
27+
return Object.assign({}, themeDefault, themeDark);
28+
}
29+
30+
return themeDefault;
31+
}
32+
2333
// Actions
2434
@action _openSettings({ path = '/settings' }) {
2535
const settingsPath = path !== '/settings' ? `/settings/${path}` : path;

0 commit comments

Comments
 (0)