diff options
-rw-r--r-- | gulpfile.babel.js | 13 | ||||
-rw-r--r-- | package-lock.json | 165 | ||||
-rw-r--r-- | package.json | 5 | ||||
-rw-r--r-- | src/components/settings/navigation/SettingsNavigation.js | 3 | ||||
-rw-r--r-- | src/containers/layout/AppLayoutContainer.js | 43 | ||||
-rw-r--r-- | src/stores/UIStore.js | 10 | ||||
-rw-r--r-- | src/styles/colors.scss | 50 | ||||
-rw-r--r-- | src/styles/type-helper.scss | 100 | ||||
-rw-r--r-- | src/theme/dark/index.js | 5 | ||||
-rw-r--r-- | src/theme/default/index.js | 12 | ||||
-rw-r--r-- | src/theme/default/legacy.js | 39 |
11 files changed, 396 insertions, 49 deletions
diff --git a/gulpfile.babel.js b/gulpfile.babel.js index ad8adda2e..cea42d6c9 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js | |||
@@ -7,11 +7,20 @@ import { exec } from 'child_process'; | |||
7 | import dotenv from 'dotenv'; | 7 | import dotenv from 'dotenv'; |
8 | import sassVariables from 'gulp-sass-variables'; | 8 | import sassVariables from 'gulp-sass-variables'; |
9 | import { removeSync } from 'fs-extra'; | 9 | import { removeSync } from 'fs-extra'; |
10 | import kebabCase from 'kebab-case'; | ||
11 | import hexRgb from 'hex-rgb'; | ||
10 | 12 | ||
11 | import config from './package.json'; | 13 | import config from './package.json'; |
12 | 14 | ||
15 | import * as rawStyleConfig from './src/theme/default/legacy.js'; | ||
16 | |||
13 | dotenv.config(); | 17 | dotenv.config(); |
14 | 18 | ||
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 | |||
15 | const paths = { | 24 | const paths = { |
16 | src: 'src', | 25 | src: 'src', |
17 | dest: 'build', | 26 | dest: 'build', |
@@ -83,9 +92,9 @@ export function html() { | |||
83 | 92 | ||
84 | export function styles() { | 93 | export function styles() { |
85 | return gulp.src(paths.styles.src) | 94 | return gulp.src(paths.styles.src) |
86 | .pipe(sassVariables({ | 95 | .pipe(sassVariables(Object.assign({ |
87 | $env: process.env.NODE_ENV === 'development' ? 'development' : 'production', | 96 | $env: process.env.NODE_ENV === 'development' ? 'development' : 'production', |
88 | })) | 97 | }, ...styleConfig))) |
89 | .pipe(sass({ | 98 | .pipe(sass({ |
90 | includePaths: [ | 99 | includePaths: [ |
91 | './node_modules', | 100 | './node_modules', |
diff --git a/package-lock.json b/package-lock.json index 1dcd57e01..6f1f11eba 100644 --- a/package-lock.json +++ b/package-lock.json | |||
@@ -2006,6 +2006,11 @@ | |||
2006 | } | 2006 | } |
2007 | } | 2007 | } |
2008 | }, | 2008 | }, |
2009 | "brcast": { | ||
2010 | "version": "3.0.1", | ||
2011 | "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.1.tgz", | ||
2012 | "integrity": "sha512-eI3yqf9YEqyGl9PCNTR46MGvDylGtaHjalcz6Q3fAPnP/PhpKkkve52vFdfGpwp4VUvK6LUr4TQN+2stCrEwTg==" | ||
2013 | }, | ||
2009 | "browserslist": { | 2014 | "browserslist": { |
2010 | "version": "4.3.2", | 2015 | "version": "4.3.2", |
2011 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.2.tgz", | 2016 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.2.tgz", |
@@ -3010,6 +3015,14 @@ | |||
3010 | "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", | 3015 | "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", |
3011 | "dev": true | 3016 | "dev": true |
3012 | }, | 3017 | }, |
3018 | "css-vendor": { | ||
3019 | "version": "0.3.8", | ||
3020 | "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", | ||
3021 | "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=", | ||
3022 | "requires": { | ||
3023 | "is-in-browser": "^1.0.2" | ||
3024 | } | ||
3025 | }, | ||
3013 | "currently-unhandled": { | 3026 | "currently-unhandled": { |
3014 | "version": "0.4.1", | 3027 | "version": "0.4.1", |
3015 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", | 3028 | "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", |
@@ -6745,6 +6758,12 @@ | |||
6745 | "resolved": "https://registry.npmjs.org/hashids/-/hashids-1.2.2.tgz", | 6758 | "resolved": "https://registry.npmjs.org/hashids/-/hashids-1.2.2.tgz", |
6746 | "integrity": "sha512-dEHCG2LraR6PNvSGxosZHIRgxF5sNLOIBFEHbj8lfP9WWmu/PWPMzsip1drdVSOFi51N2pU7gZavrgn7sbGFuw==" | 6759 | "integrity": "sha512-dEHCG2LraR6PNvSGxosZHIRgxF5sNLOIBFEHbj8lfP9WWmu/PWPMzsip1drdVSOFi51N2pU7gZavrgn7sbGFuw==" |
6747 | }, | 6760 | }, |
6761 | "hex-rgb": { | ||
6762 | "version": "3.0.0", | ||
6763 | "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-3.0.0.tgz", | ||
6764 | "integrity": "sha512-iWOUTZu7KQGhErV8JfTQDH5F/M2D0HVd0sexS4Grg4e4RYAiN3c4jfpPqKgfedqeebKcNZBl2z3zlgCtFjpFJQ==", | ||
6765 | "dev": true | ||
6766 | }, | ||
6748 | "history": { | 6767 | "history": { |
6749 | "version": "3.3.0", | 6768 | "version": "3.3.0", |
6750 | "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", | 6769 | "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz", |
@@ -6967,6 +6986,11 @@ | |||
6967 | } | 6986 | } |
6968 | } | 6987 | } |
6969 | }, | 6988 | }, |
6989 | "hyphenate-style-name": { | ||
6990 | "version": "1.0.2", | ||
6991 | "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz", | ||
6992 | "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=" | ||
6993 | }, | ||
6970 | "iconv-lite": { | 6994 | "iconv-lite": { |
6971 | "version": "0.4.24", | 6995 | "version": "0.4.24", |
6972 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", | 6996 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", |
@@ -7352,6 +7376,11 @@ | |||
7352 | "number-is-nan": "^1.0.0" | 7376 | "number-is-nan": "^1.0.0" |
7353 | } | 7377 | } |
7354 | }, | 7378 | }, |
7379 | "is-function": { | ||
7380 | "version": "1.0.1", | ||
7381 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", | ||
7382 | "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" | ||
7383 | }, | ||
7355 | "is-glob": { | 7384 | "is-glob": { |
7356 | "version": "4.0.0", | 7385 | "version": "4.0.0", |
7357 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", | 7386 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", |
@@ -7361,6 +7390,11 @@ | |||
7361 | "is-extglob": "^2.1.1" | 7390 | "is-extglob": "^2.1.1" |
7362 | } | 7391 | } |
7363 | }, | 7392 | }, |
7393 | "is-in-browser": { | ||
7394 | "version": "1.1.3", | ||
7395 | "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", | ||
7396 | "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" | ||
7397 | }, | ||
7364 | "is-installed-globally": { | 7398 | "is-installed-globally": { |
7365 | "version": "0.1.0", | 7399 | "version": "0.1.0", |
7366 | "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", | 7400 | "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", |
@@ -7727,6 +7761,108 @@ | |||
7727 | "verror": "1.10.0" | 7761 | "verror": "1.10.0" |
7728 | } | 7762 | } |
7729 | }, | 7763 | }, |
7764 | "jss": { | ||
7765 | "version": "9.8.7", | ||
7766 | "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", | ||
7767 | "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", | ||
7768 | "requires": { | ||
7769 | "is-in-browser": "^1.1.3", | ||
7770 | "symbol-observable": "^1.1.0", | ||
7771 | "warning": "^3.0.0" | ||
7772 | }, | ||
7773 | "dependencies": { | ||
7774 | "symbol-observable": { | ||
7775 | "version": "1.2.0", | ||
7776 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", | ||
7777 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" | ||
7778 | } | ||
7779 | } | ||
7780 | }, | ||
7781 | "jss-camel-case": { | ||
7782 | "version": "6.1.0", | ||
7783 | "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz", | ||
7784 | "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==", | ||
7785 | "requires": { | ||
7786 | "hyphenate-style-name": "^1.0.2" | ||
7787 | } | ||
7788 | }, | ||
7789 | "jss-compose": { | ||
7790 | "version": "5.0.0", | ||
7791 | "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz", | ||
7792 | "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==", | ||
7793 | "requires": { | ||
7794 | "warning": "^3.0.0" | ||
7795 | } | ||
7796 | }, | ||
7797 | "jss-default-unit": { | ||
7798 | "version": "8.0.2", | ||
7799 | "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz", | ||
7800 | "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==" | ||
7801 | }, | ||
7802 | "jss-expand": { | ||
7803 | "version": "5.3.0", | ||
7804 | "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz", | ||
7805 | "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg==" | ||
7806 | }, | ||
7807 | "jss-extend": { | ||
7808 | "version": "6.2.0", | ||
7809 | "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz", | ||
7810 | "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==", | ||
7811 | "requires": { | ||
7812 | "warning": "^3.0.0" | ||
7813 | } | ||
7814 | }, | ||
7815 | "jss-global": { | ||
7816 | "version": "3.0.0", | ||
7817 | "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", | ||
7818 | "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==" | ||
7819 | }, | ||
7820 | "jss-nested": { | ||
7821 | "version": "6.0.1", | ||
7822 | "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", | ||
7823 | "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", | ||
7824 | "requires": { | ||
7825 | "warning": "^3.0.0" | ||
7826 | } | ||
7827 | }, | ||
7828 | "jss-preset-default": { | ||
7829 | "version": "4.5.0", | ||
7830 | "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz", | ||
7831 | "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==", | ||
7832 | "requires": { | ||
7833 | "jss-camel-case": "^6.1.0", | ||
7834 | "jss-compose": "^5.0.0", | ||
7835 | "jss-default-unit": "^8.0.2", | ||
7836 | "jss-expand": "^5.3.0", | ||
7837 | "jss-extend": "^6.2.0", | ||
7838 | "jss-global": "^3.0.0", | ||
7839 | "jss-nested": "^6.0.1", | ||
7840 | "jss-props-sort": "^6.0.0", | ||
7841 | "jss-template": "^1.0.1", | ||
7842 | "jss-vendor-prefixer": "^7.0.0" | ||
7843 | } | ||
7844 | }, | ||
7845 | "jss-props-sort": { | ||
7846 | "version": "6.0.0", | ||
7847 | "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", | ||
7848 | "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==" | ||
7849 | }, | ||
7850 | "jss-template": { | ||
7851 | "version": "1.0.1", | ||
7852 | "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz", | ||
7853 | "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==", | ||
7854 | "requires": { | ||
7855 | "warning": "^3.0.0" | ||
7856 | } | ||
7857 | }, | ||
7858 | "jss-vendor-prefixer": { | ||
7859 | "version": "7.0.0", | ||
7860 | "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", | ||
7861 | "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", | ||
7862 | "requires": { | ||
7863 | "css-vendor": "^0.3.8" | ||
7864 | } | ||
7865 | }, | ||
7730 | "jsx-ast-utils": { | 7866 | "jsx-ast-utils": { |
7731 | "version": "1.4.1", | 7867 | "version": "1.4.1", |
7732 | "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", | 7868 | "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", |
@@ -7758,6 +7894,12 @@ | |||
7758 | "safe-buffer": "^5.0.1" | 7894 | "safe-buffer": "^5.0.1" |
7759 | } | 7895 | } |
7760 | }, | 7896 | }, |
7897 | "kebab-case": { | ||
7898 | "version": "1.0.0", | ||
7899 | "resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.0.tgz", | ||
7900 | "integrity": "sha1-P55JkK3K0MaGwOcB92RYaPdfkes=", | ||
7901 | "dev": true | ||
7902 | }, | ||
7761 | "keymaster": { | 7903 | "keymaster": { |
7762 | "version": "1.6.2", | 7904 | "version": "1.6.2", |
7763 | "resolved": "https://registry.npmjs.org/keymaster/-/keymaster-1.6.2.tgz", | 7905 | "resolved": "https://registry.npmjs.org/keymaster/-/keymaster-1.6.2.tgz", |
@@ -9690,6 +9832,18 @@ | |||
9690 | "invariant": "^2.1.1" | 9832 | "invariant": "^2.1.1" |
9691 | } | 9833 | } |
9692 | }, | 9834 | }, |
9835 | "react-jss": { | ||
9836 | "version": "8.6.1", | ||
9837 | "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", | ||
9838 | "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==", | ||
9839 | "requires": { | ||
9840 | "hoist-non-react-statics": "^2.5.0", | ||
9841 | "jss": "^9.7.0", | ||
9842 | "jss-preset-default": "^4.3.0", | ||
9843 | "prop-types": "^15.6.0", | ||
9844 | "theming": "^1.3.0" | ||
9845 | } | ||
9846 | }, | ||
9693 | "react-lifecycles-compat": { | 9847 | "react-lifecycles-compat": { |
9694 | "version": "3.0.4", | 9848 | "version": "3.0.4", |
9695 | "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", | 9849 | "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", |
@@ -11168,6 +11322,17 @@ | |||
11168 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", | 11322 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", |
11169 | "dev": true | 11323 | "dev": true |
11170 | }, | 11324 | }, |
11325 | "theming": { | ||
11326 | "version": "1.3.0", | ||
11327 | "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz", | ||
11328 | "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==", | ||
11329 | "requires": { | ||
11330 | "brcast": "^3.0.1", | ||
11331 | "is-function": "^1.0.1", | ||
11332 | "is-plain-object": "^2.0.1", | ||
11333 | "prop-types": "^15.5.8" | ||
11334 | } | ||
11335 | }, | ||
11171 | "throttleit": { | 11336 | "throttleit": { |
11172 | "version": "0.0.2", | 11337 | "version": "0.0.2", |
11173 | "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", | 11338 | "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", |
diff --git a/package.json b/package.json index ee2b12e99..8ec2d4f67 100644 --- a/package.json +++ b/package.json | |||
@@ -11,7 +11,7 @@ | |||
11 | "private": true, | 11 | "private": true, |
12 | "scripts": { | 12 | "scripts": { |
13 | "prestart": "npm run rebuild", | 13 | "prestart": "npm run rebuild", |
14 | "start": "DEBUG=Franz:* electron ./build", | 14 | "start": "electron ./build", |
15 | "start:local": "cross-env LOCAL_API=1 npm start", | 15 | "start:local": "cross-env LOCAL_API=1 npm start", |
16 | "start:live": "cross-env LIVE_API=1 npm start", | 16 | "start:live": "cross-env LIVE_API=1 npm start", |
17 | "dev": "cross-env NODE_ENV=development gulp dev", | 17 | "dev": "cross-env NODE_ENV=development gulp dev", |
@@ -67,6 +67,7 @@ | |||
67 | "react-dropzone": "^4.2.1", | 67 | "react-dropzone": "^4.2.1", |
68 | "react-electron-web-view": "^2.0.1", | 68 | "react-electron-web-view": "^2.0.1", |
69 | "react-intl": "^2.3.0", | 69 | "react-intl": "^2.3.0", |
70 | "react-jss": "8.6.1", | ||
70 | "react-loader": "^2.4.0", | 71 | "react-loader": "^2.4.0", |
71 | "react-router": "^3.0.2", | 72 | "react-router": "^3.0.2", |
72 | "react-router-transition": "^0.1.1", | 73 | "react-router-transition": "^0.1.1", |
@@ -108,7 +109,9 @@ | |||
108 | "gulp-sass": "^4.0.2", | 109 | "gulp-sass": "^4.0.2", |
109 | "gulp-sass-variables": "^1.1.1", | 110 | "gulp-sass-variables": "^1.1.1", |
110 | "gulp-server-livereload": "^1.9.2", | 111 | "gulp-server-livereload": "^1.9.2", |
112 | "hex-rgb": "3.0.0", | ||
111 | "husky": "^1.1.4", | 113 | "husky": "^1.1.4", |
114 | "kebab-case": "1.0.0", | ||
112 | "node-sass": "^4.7.2", | 115 | "node-sass": "^4.7.2", |
113 | "prettier": "1.15.2" | 116 | "prettier": "1.15.2" |
114 | }, | 117 | }, |
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js index 46b2f82fc..d8b410aaf 100644 --- a/src/components/settings/navigation/SettingsNavigation.js +++ b/src/components/settings/navigation/SettingsNavigation.js | |||
@@ -32,8 +32,7 @@ const messages = defineMessages({ | |||
32 | }, | 32 | }, |
33 | }); | 33 | }); |
34 | 34 | ||
35 | @inject('stores') @observer | 35 | export default @inject('stores') @observer class SettingsNavigation extends Component { |
36 | export default class SettingsNavigation extends Component { | ||
37 | static propTypes = { | 36 | static propTypes = { |
38 | serviceCount: PropTypes.number.isRequired, | 37 | serviceCount: PropTypes.number.isRequired, |
39 | }; | 38 | }; |
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index affc1a0a2..c5c9c6850 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js | |||
@@ -1,6 +1,7 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
4 | import { ThemeProvider } from 'react-jss'; | ||
4 | 5 | ||
5 | import AppStore from '../../stores/AppStore'; | 6 | import AppStore from '../../stores/AppStore'; |
6 | import RecipesStore from '../../stores/RecipesStore'; | 7 | import RecipesStore from '../../stores/RecipesStore'; |
@@ -109,26 +110,28 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
109 | ); | 110 | ); |
110 | 111 | ||
111 | return ( | 112 | return ( |
112 | <AppLayout | 113 | <ThemeProvider theme={ui.theme}> |
113 | isFullScreen={app.isFullScreen} | 114 | <AppLayout |
114 | isOnline={app.isOnline} | 115 | isFullScreen={app.isFullScreen} |
115 | showServicesUpdatedInfoBar={ui.showServicesUpdatedInfoBar} | 116 | isOnline={app.isOnline} |
116 | appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED} | 117 | showServicesUpdatedInfoBar={ui.showServicesUpdatedInfoBar} |
117 | sidebar={sidebar} | 118 | appUpdateIsDownloaded={app.updateStatus === app.updateStatusTypes.DOWNLOADED} |
118 | services={servicesContainer} | 119 | sidebar={sidebar} |
119 | news={news.latest} | 120 | services={servicesContainer} |
120 | removeNewsItem={hide} | 121 | news={news.latest} |
121 | reloadServicesAfterUpdate={reloadUpdatedServices} | 122 | removeNewsItem={hide} |
122 | installAppUpdate={installUpdate} | 123 | reloadServicesAfterUpdate={reloadUpdatedServices} |
123 | globalError={globalError.error} | 124 | installAppUpdate={installUpdate} |
124 | showRequiredRequestsError={requests.showRequiredRequestsError} | 125 | globalError={globalError.error} |
125 | areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful} | 126 | showRequiredRequestsError={requests.showRequiredRequestsError} |
126 | retryRequiredRequests={retryRequiredRequests} | 127 | areRequiredRequestsSuccessful={requests.areRequiredRequestsSuccessful} |
127 | areRequiredRequestsLoading={requests.areRequiredRequestsLoading} | 128 | retryRequiredRequests={retryRequiredRequests} |
128 | darkMode={settings.all.app.darkMode} | 129 | areRequiredRequestsLoading={requests.areRequiredRequestsLoading} |
129 | > | 130 | darkMode={settings.all.app.darkMode} |
130 | {React.Children.count(children) > 0 ? children : null} | 131 | > |
131 | </AppLayout> | 132 | {React.Children.count(children) > 0 ? children : null} |
133 | </AppLayout> | ||
134 | </ThemeProvider> | ||
132 | ); | 135 | ); |
133 | } | 136 | } |
134 | } | 137 | } |
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index bee6c8bcf..d37ebe4c7 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js | |||
@@ -1,6 +1,8 @@ | |||
1 | import { action, observable, computed } from 'mobx'; | 1 | import { action, observable, computed } from 'mobx'; |
2 | 2 | ||
3 | import Store from './lib/Store'; | 3 | import Store from './lib/Store'; |
4 | import * as themeDefault from '../theme/default'; | ||
5 | import * as themeDark from '../theme/dark'; | ||
4 | 6 | ||
5 | export default class UIStore extends Store { | 7 | export default class UIStore extends Store { |
6 | @observable showServicesUpdatedInfoBar = false; | 8 | @observable showServicesUpdatedInfoBar = false; |
@@ -20,6 +22,14 @@ export default class UIStore extends Store { | |||
20 | return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.isAppMuted; | 22 | return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.isAppMuted; |
21 | } | 23 | } |
22 | 24 | ||
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 | |||
23 | // Actions | 33 | // Actions |
24 | @action _openSettings({ path = '/settings' }) { | 34 | @action _openSettings({ path = '/settings' }) { |
25 | const settingsPath = path !== '/settings' ? `/settings/${path}` : path; | 35 | const settingsPath = path !== '/settings' ? `/settings/${path}` : path; |
diff --git a/src/styles/colors.scss b/src/styles/colors.scss index 4411a0e81..80c2fb633 100644 --- a/src/styles/colors.scss +++ b/src/styles/colors.scss | |||
@@ -1,38 +1,40 @@ | |||
1 | $theme-brand-primary: #3498db; | 1 | @import "./type-helper"; |
2 | $theme-brand-success: #5cb85c; | ||
3 | $theme-brand-info: #5bc0de; | ||
4 | $theme-brand-warning: #FF9F00; | ||
5 | $theme-brand-danger: #d9534f; | ||
6 | 2 | ||
7 | $theme-gray-dark: #373a3c; | 3 | $theme-brand-primary: convert-rgb-string-to-color($raw-theme-brand-primary); |
8 | $theme-gray: #55595c; | 4 | $theme-brand-success: convert-rgb-string-to-color($raw-theme-brand-success); |
9 | $theme-gray-light: #818a91; | 5 | $theme-brand-info: convert-rgb-string-to-color($raw-theme-brand-info); |
10 | $theme-gray-lighter: #eceeef; | 6 | $theme-brand-warning: convert-rgb-string-to-color($raw-theme-brand-warning); |
11 | $theme-gray-lightest: #f7f7f9; | 7 | $theme-brand-danger: convert-rgb-string-to-color($raw-theme-brand-danger); |
12 | 8 | ||
13 | $theme-border-radius: 6px; | 9 | $theme-gray-dark: convert-rgb-string-to-color($raw-theme-gray-dark); |
14 | $theme-border-radius-small: 3px; | 10 | $theme-gray: convert-rgb-string-to-color($raw-theme-gray); |
11 | $theme-gray-light: convert-rgb-string-to-color($raw-theme-gray-light); | ||
12 | $theme-gray-lighter: convert-rgb-string-to-color($raw-theme-gray-lighter); | ||
13 | $theme-gray-lightest: convert-rgb-string-to-color($raw-theme-gray-lightest); | ||
15 | 14 | ||
16 | $theme-sidebar-width: 68px; | 15 | $theme-border-radius: to-number($raw-theme-border-radius); |
16 | $theme-border-radius-small: to-number($raw-theme-border-radius-small); | ||
17 | 17 | ||
18 | $theme-text-color: $theme-gray-dark; | 18 | $theme-sidebar-width: to-number($raw-theme-sidebar-width); |
19 | |||
20 | $theme-text-color: convert-rgb-string-to-color($raw-theme-gray-dark); | ||
19 | 21 | ||
20 | $theme-transition-time: .5s; | 22 | $theme-transition-time: .5s; |
21 | 23 | ||
22 | $theme-inset-shadow: inset 0 2px 5px rgba(0, 0, 0, .03); | 24 | $theme-inset-shadow: inset 0 2px 5px rgba(0, 0, 0, .03); |
23 | 25 | ||
24 | // Dark Theme | 26 | // Dark Theme |
25 | $dark-theme-black: #1A1A1A; | 27 | $dark-theme-black: convert-rgb-string-to-color($raw-dark-theme-black); |
26 | 28 | ||
27 | $dark-theme-gray-darkest: #1E1E1E; | 29 | $dark-theme-gray-darkest: convert-rgb-string-to-color($raw-dark-theme-gray-darkest); |
28 | $dark-theme-gray-darker: #2D2F31; | 30 | $dark-theme-gray-darker: convert-rgb-string-to-color($raw-dark-theme-gray-darker); |
29 | $dark-theme-gray-dark: #383A3B; | 31 | $dark-theme-gray-dark: convert-rgb-string-to-color($raw-dark-theme-gray-dark); |
30 | 32 | ||
31 | $dark-theme-gray: #47494B; | 33 | $dark-theme-gray: convert-rgb-string-to-color($raw-dark-theme-gray); |
32 | 34 | ||
33 | $dark-theme-gray-light: #515355; | 35 | $dark-theme-gray-light: convert-rgb-string-to-color($raw-dark-theme-gray-light); |
34 | $dark-theme-gray-lighter: #8a8b8b; | 36 | $dark-theme-gray-lighter: convert-rgb-string-to-color($raw-dark-theme-gray-lighter); |
35 | $dark-theme-gray-lightest: #FFF; | 37 | $dark-theme-gray-lightest: convert-rgb-string-to-color($raw-dark-theme-gray-lightest); |
36 | 38 | ||
37 | $dark-theme-gray-smoke: #CED0D1; | 39 | $dark-theme-gray-smoke: convert-rgb-string-to-color($raw-dark-theme-gray-smoke); |
38 | $dark-theme-text-color: #FFF; | 40 | $dark-theme-text-color: convert-rgb-string-to-color($raw-dark-theme-text-color); |
diff --git a/src/styles/type-helper.scss b/src/styles/type-helper.scss new file mode 100644 index 000000000..b1da394b5 --- /dev/null +++ b/src/styles/type-helper.scss | |||
@@ -0,0 +1,100 @@ | |||
1 | @function str-split($string, $separator) { | ||
2 | // empty array/list | ||
3 | $split-arr: (); | ||
4 | // first index of separator in string | ||
5 | $index : str-index($string, $separator); | ||
6 | // loop through string | ||
7 | @while $index != null { | ||
8 | // get the substring from the first character to the separator | ||
9 | $item: str-slice($string, 1, $index - 1); | ||
10 | // push item to array | ||
11 | $split-arr: append($split-arr, $item); | ||
12 | // remove item and separator from string | ||
13 | $string: str-slice($string, $index + 1); | ||
14 | // find new index of separator | ||
15 | $index : str-index($string, $separator); | ||
16 | } | ||
17 | // add the remaining string to list (the last item) | ||
18 | $split-arr: append($split-arr, $string); | ||
19 | |||
20 | @return $split-arr; | ||
21 | } | ||
22 | |||
23 | // ---- | ||
24 | // Sass (v3.4.13) | ||
25 | // Compass (v1.0.3) | ||
26 | // ---- | ||
27 | |||
28 | /// String to number converter | ||
29 | /// @author Hugo Giraudel | ||
30 | /// @access private | ||
31 | |||
32 | |||
33 | /// Casts a string into a number | ||
34 | /// | ||
35 | /// @param {String | Number} $value - Value to be parsed | ||
36 | /// | ||
37 | /// @return {Number} | ||
38 | |||
39 | @function to-number($value) { | ||
40 | @if type-of($value) == 'number' { | ||
41 | @return $value; | ||
42 | } @else if type-of($value) != 'string' { | ||
43 | $_: log('Value for `to-number` should be a number or a string.'); | ||
44 | } | ||
45 | |||
46 | $result: 0; | ||
47 | $digits: 0; | ||
48 | $minus: str-slice($value, 1, 1) == '-'; | ||
49 | $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9); | ||
50 | |||
51 | @for $i from if($minus, 2, 1) through str-length($value) { | ||
52 | $character: str-slice($value, $i, $i); | ||
53 | |||
54 | @if not (index(map-keys($numbers), $character) or $character == '.') { | ||
55 | @return to-length(if($minus, -$result, $result), str-slice($value, $i)) | ||
56 | } | ||
57 | |||
58 | @if $character == '.' { | ||
59 | $digits: 1; | ||
60 | } @else if $digits == 0 { | ||
61 | $result: $result * 10 + map-get($numbers, $character); | ||
62 | } @else { | ||
63 | $digits: $digits * 10; | ||
64 | $result: $result + map-get($numbers, $character) / $digits; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | @return if($minus, -$result, $result);; | ||
69 | } | ||
70 | |||
71 | |||
72 | /// Add `$unit` to `$value` | ||
73 | /// | ||
74 | /// @param {Number} $value - Value to add unit to | ||
75 | /// @param {String} $unit - String representation of the unit | ||
76 | /// | ||
77 | /// @return {Number} - `$value` expressed in `$unit` | ||
78 | @function to-length($value, $unit) { | ||
79 | $units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax); | ||
80 | |||
81 | @if not index(map-keys($units), $unit) { | ||
82 | $_: log('Invalid unit `#{$unit}`.'); | ||
83 | } | ||
84 | |||
85 | @return $value * map-get($units, $unit); | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | /// converts injectes rgb strings to sass colors | ||
91 | @function convert-rgb-string-to-color($string) { | ||
92 | $values: str-split($string, ','); | ||
93 | $colorList: (); | ||
94 | @each $value in $values { | ||
95 | $colorList: append($colorList, to-number($value)); | ||
96 | } | ||
97 | |||
98 | $rgbaColor: rgb(nth($colorList, 1), nth($colorList, 2), nth($colorList, 3)); | ||
99 | @return $rgbaColor; | ||
100 | } \ No newline at end of file | ||
diff --git a/src/theme/dark/index.js b/src/theme/dark/index.js new file mode 100644 index 000000000..e0e017c7c --- /dev/null +++ b/src/theme/dark/index.js | |||
@@ -0,0 +1,5 @@ | |||
1 | import * as legacyStyles from '../default/legacy'; | ||
2 | |||
3 | export const colorBackground = legacyStyles.darkThemeGrayDarkest; | ||
4 | |||
5 | export const colorHeadline = legacyStyles.darkThemeTextColor; | ||
diff --git a/src/theme/default/index.js b/src/theme/default/index.js new file mode 100644 index 000000000..f8b6e898d --- /dev/null +++ b/src/theme/default/index.js | |||
@@ -0,0 +1,12 @@ | |||
1 | import * as legacyStyles from './legacy'; | ||
2 | |||
3 | /* legacy config, injected into sass */ | ||
4 | export const themeBrandPrimary = '#3498db'; | ||
5 | export const themeBrandSuccess = '#5cb85c'; | ||
6 | export const themeBrandInfo = '#5bc0de'; | ||
7 | export const themeBrandWarning = '#FF9F00'; | ||
8 | export const themeBrandDanger = '#d9534f'; | ||
9 | |||
10 | export const colorBackground = legacyStyles.themeGrayLighter; | ||
11 | |||
12 | export const colorHeadline = legacyStyles.themeGrayDark; | ||
diff --git a/src/theme/default/legacy.js b/src/theme/default/legacy.js new file mode 100644 index 000000000..b676dc1d9 --- /dev/null +++ b/src/theme/default/legacy.js | |||
@@ -0,0 +1,39 @@ | |||
1 | /* legacy config, injected into sass */ | ||
2 | export const themeBrandPrimary = '#3498db'; | ||
3 | export const themeBrandSuccess = '#5cb85c'; | ||
4 | export const themeBrandInfo = '#5bc0de'; | ||
5 | export const themeBrandWarning = '#FF9F00'; | ||
6 | export const themeBrandDanger = '#d9534f'; | ||
7 | |||
8 | export const themeGrayDark = '#373a3c'; | ||
9 | export const themeGray = '#55595c'; | ||
10 | export const themeGrayLight = '#818a91'; | ||
11 | export const themeGrayLighter = '#eceeef'; | ||
12 | export const themeGrayLightest = '#f7f7f9'; | ||
13 | |||
14 | export const themeBorderRadius = '6px'; | ||
15 | export const themeBorderRadiusSmall = '3px'; | ||
16 | |||
17 | export const themeSidebarWidth = '68px'; | ||
18 | |||
19 | export const themeTextColor = themeGrayDark; | ||
20 | |||
21 | export const themeTransitionTime = '.5s'; | ||
22 | |||
23 | export const themeInsetShadow = 'inset 0 2px 5px rgba(0, 0, 0, .03)'; | ||
24 | |||
25 | |||
26 | export const darkThemeBlack = '#1A1A1A'; | ||
27 | |||
28 | export const darkThemeGrayDarkest = '#1E1E1E'; | ||
29 | export const darkThemeGrayDarker = '#2D2F31'; | ||
30 | export const darkThemeGrayDark = '#383A3B'; | ||
31 | |||
32 | export const darkThemeGray = '#47494B'; | ||
33 | |||
34 | export const darkThemeGrayLight = '#515355'; | ||
35 | export const darkThemeGrayLighter = '#8a8b8b'; | ||
36 | export const darkThemeGrayLightest = '#FFFFFF'; | ||
37 | |||
38 | export const darkThemeGraySmoke = '#CED0D1'; | ||
39 | export const darkThemeTextColor = '#FFFFFF'; | ||