Compare commits
383 Commits
20200312.0
...
add-import
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f995d8d525 | ||
![]() |
e83ede245d | ||
![]() |
05ac275780 | ||
![]() |
966c0bc06c | ||
![]() |
abf136dd63 | ||
![]() |
b6309cfd16 | ||
![]() |
b69d5e0fa3 | ||
![]() |
5084cde6b9 | ||
![]() |
ca1cc7ed0d | ||
![]() |
808a31db2b | ||
![]() |
44ad75aead | ||
![]() |
0961c9d05e | ||
![]() |
56754b4d43 | ||
![]() |
661779ad4e | ||
![]() |
cf37ebb652 | ||
![]() |
82741e490b | ||
![]() |
5fed28808e | ||
![]() |
321c0cfc84 | ||
![]() |
eba7cedaa6 | ||
![]() |
71492d0467 | ||
![]() |
9630a58ea7 | ||
![]() |
89f6f16ba2 | ||
![]() |
2d646da97f | ||
![]() |
39b5460598 | ||
![]() |
636429ccfa | ||
![]() |
e5abb95f5c | ||
![]() |
c631554eb0 | ||
![]() |
db07eeb916 | ||
![]() |
3216a46e76 | ||
![]() |
df002d7a67 | ||
![]() |
e8a0632108 | ||
![]() |
0a92c28bac | ||
![]() |
d419547463 | ||
![]() |
da392912b3 | ||
![]() |
9ebee02727 | ||
![]() |
0bdcfcc42f | ||
![]() |
43623a30bc | ||
![]() |
99e73054a9 | ||
![]() |
108233f3b8 | ||
![]() |
8f2a7c95b3 | ||
![]() |
7fdd525dac | ||
![]() |
7ed24137eb | ||
![]() |
07cd30eaca | ||
![]() |
df8cf66e02 | ||
![]() |
f067bcd877 | ||
![]() |
e11ef55dd8 | ||
![]() |
fa8bd30e83 | ||
![]() |
04a2ff7506 | ||
![]() |
bc68e20041 | ||
![]() |
786da25b9f | ||
![]() |
c3832d56c3 | ||
![]() |
79d1a2f458 | ||
![]() |
f16a674a39 | ||
![]() |
6e38a80efc | ||
![]() |
6a3a1297ad | ||
![]() |
5ca63a8052 | ||
![]() |
8b04df093c | ||
![]() |
d2a5494335 | ||
![]() |
de545e90e2 | ||
![]() |
57ab7e829b | ||
![]() |
6847830575 | ||
![]() |
2084ecc4c6 | ||
![]() |
b0c27e587e | ||
![]() |
1687d90d02 | ||
![]() |
dfd9bf3c64 | ||
![]() |
5a25b9c2f1 | ||
![]() |
bf68101754 | ||
![]() |
487bd8d3fc | ||
![]() |
3ba9c931b9 | ||
![]() |
8484f7595a | ||
![]() |
ee889d59d4 | ||
![]() |
ae10330844 | ||
![]() |
f3e88f6f2e | ||
![]() |
2abfd0392d | ||
![]() |
462c1f94d6 | ||
![]() |
f4710891d0 | ||
![]() |
1fdb6b8034 | ||
![]() |
8029c3d672 | ||
![]() |
61fdee14c6 | ||
![]() |
117e4e468f | ||
![]() |
869ec113f4 | ||
![]() |
00e7b93011 | ||
![]() |
03e581870a | ||
![]() |
b04fe141ac | ||
![]() |
b0168fbb85 | ||
![]() |
75ba343b5e | ||
![]() |
88217473f7 | ||
![]() |
01e5dfc9b3 | ||
![]() |
58869677bd | ||
![]() |
032b01aec1 | ||
![]() |
a47c3fa854 | ||
![]() |
7c6ba1a782 | ||
![]() |
0d08f5413b | ||
![]() |
949cc17a9e | ||
![]() |
607c1a1ef0 | ||
![]() |
db2dab8227 | ||
![]() |
eb4ba4fc78 | ||
![]() |
bf888b1547 | ||
![]() |
c468aab9b2 | ||
![]() |
a0dae802f2 | ||
![]() |
14330fbd93 | ||
![]() |
bf55be7f7f | ||
![]() |
e10987a705 | ||
![]() |
355f40d740 | ||
![]() |
2503fabe1d | ||
![]() |
32c7c0b4f0 | ||
![]() |
301a964a65 | ||
![]() |
49f2fd2af7 | ||
![]() |
4f518cac2c | ||
![]() |
8420f73919 | ||
![]() |
1ef2d3c7f2 | ||
![]() |
fc20fd32f1 | ||
![]() |
13a8bf6993 | ||
![]() |
b2f424a6f8 | ||
![]() |
a9d927551c | ||
![]() |
fdf7b516a0 | ||
![]() |
9a00078169 | ||
![]() |
1dfb632fc4 | ||
![]() |
1c1f9a6a89 | ||
![]() |
2b76b3887e | ||
![]() |
a49c84032b | ||
![]() |
c72bb5b22b | ||
![]() |
24a844dddc | ||
![]() |
ae903973a7 | ||
![]() |
82442bb5ec | ||
![]() |
8786302190 | ||
![]() |
d27a17cf8e | ||
![]() |
b4b90ca59d | ||
![]() |
ecd967a68d | ||
![]() |
8812340768 | ||
![]() |
659da7bf80 | ||
![]() |
91eabf3c38 | ||
![]() |
e355c81e41 | ||
![]() |
d45a674652 | ||
![]() |
f91b46e88c | ||
![]() |
f57754212c | ||
![]() |
97c454aa0d | ||
![]() |
b516f10a35 | ||
![]() |
0ccc788148 | ||
![]() |
5c941e0afb | ||
![]() |
492e4d2df4 | ||
![]() |
66f33ad497 | ||
![]() |
ff81536463 | ||
![]() |
ba0cba1a2b | ||
![]() |
fc7771ec13 | ||
![]() |
4c3069e5b7 | ||
![]() |
ed54a185e4 | ||
![]() |
4f81085d0f | ||
![]() |
8383caf6a6 | ||
![]() |
1b9f224569 | ||
![]() |
05495af74f | ||
![]() |
d62da5e924 | ||
![]() |
57d72bd80f | ||
![]() |
681c05c323 | ||
![]() |
3d20d8b208 | ||
![]() |
4f9d77b906 | ||
![]() |
82f80db558 | ||
![]() |
b17490f0de | ||
![]() |
d33c0b4bd1 | ||
![]() |
7f528c90c3 | ||
![]() |
c4c4782429 | ||
![]() |
5414092309 | ||
![]() |
b632ea6f86 | ||
![]() |
bd98ce8c25 | ||
![]() |
0c1714ef78 | ||
![]() |
ee278f111f | ||
![]() |
47e9eb5a0d | ||
![]() |
baf5dcbd03 | ||
![]() |
2e2915ec09 | ||
![]() |
5f3a6740c1 | ||
![]() |
b17074d68b | ||
![]() |
ac4b2ea70f | ||
![]() |
4e2a9e3d7b | ||
![]() |
75525b9866 | ||
![]() |
1e39f22009 | ||
![]() |
7ba55ab666 | ||
![]() |
0c06517dcc | ||
![]() |
cd1bfe1b20 | ||
![]() |
35c2d8966b | ||
![]() |
cb255ef137 | ||
![]() |
f9d78a95ad | ||
![]() |
14eb496b1d | ||
![]() |
b390e7bed1 | ||
![]() |
903f92f94a | ||
![]() |
ebb20abee0 | ||
![]() |
2253275640 | ||
![]() |
7ddfe3c80b | ||
![]() |
4388d82076 | ||
![]() |
4f70ec7dc2 | ||
![]() |
a71f42366a | ||
![]() |
e9bb9fdafe | ||
![]() |
dd49ea6f20 | ||
![]() |
92de202e0b | ||
![]() |
1d02b69f52 | ||
![]() |
1dcd913c04 | ||
![]() |
471a5f8407 | ||
![]() |
7b97ac2f6f | ||
![]() |
e673d90b3f | ||
![]() |
764234f744 | ||
![]() |
6ca944b7ef | ||
![]() |
c574556deb | ||
![]() |
c04e1adea2 | ||
![]() |
5eb11349fc | ||
![]() |
b3beb7ef85 | ||
![]() |
ec95000fbc | ||
![]() |
53f0c01073 | ||
![]() |
42d5349db7 | ||
![]() |
f36a1bbf4a | ||
![]() |
e9945abf2f | ||
![]() |
71ba192c38 | ||
![]() |
e8a7671c25 | ||
![]() |
17138f78b8 | ||
![]() |
46c6f86d6a | ||
![]() |
ae1c519d3a | ||
![]() |
fd9299cb3d | ||
![]() |
a9be870fd3 | ||
![]() |
34f61fd6dc | ||
![]() |
e568e2ae21 | ||
![]() |
0656343a91 | ||
![]() |
fa2773af9b | ||
![]() |
a438439ce0 | ||
![]() |
da73c9d83d | ||
![]() |
a8f9f7ac7a | ||
![]() |
006d989943 | ||
![]() |
82d6909957 | ||
![]() |
12a7fc9337 | ||
![]() |
0241334656 | ||
![]() |
b217291b04 | ||
![]() |
aa211df0ad | ||
![]() |
8eebf51447 | ||
![]() |
f5d834d130 | ||
![]() |
0f2eae4091 | ||
![]() |
81d2334f48 | ||
![]() |
45384205eb | ||
![]() |
4150ac045d | ||
![]() |
793a704871 | ||
![]() |
9e2606f1c8 | ||
![]() |
4c4549eb37 | ||
![]() |
96f7a4231b | ||
![]() |
c4cf248a1e | ||
![]() |
50717b4d19 | ||
![]() |
da80a3896d | ||
![]() |
cc374e0478 | ||
![]() |
26d27f8be9 | ||
![]() |
4767fcbdfc | ||
![]() |
e1b48dd2a2 | ||
![]() |
087492fc0b | ||
![]() |
525703d376 | ||
![]() |
236bc6aefa | ||
![]() |
ec4c29c52c | ||
![]() |
d5ed1c4c41 | ||
![]() |
dfe808cfb4 | ||
![]() |
da229d9b65 | ||
![]() |
e54d904e4c | ||
![]() |
2e17c96866 | ||
![]() |
ddeb16463d | ||
![]() |
465efa460e | ||
![]() |
c351402556 | ||
![]() |
5f765e8b96 | ||
![]() |
6f556f69d6 | ||
![]() |
2439827eff | ||
![]() |
5f467f82e0 | ||
![]() |
6692fa439a | ||
![]() |
0535247bb3 | ||
![]() |
a0a4fcaf5f | ||
![]() |
454d81facc | ||
![]() |
0bfa8260fa | ||
![]() |
f2124f1c95 | ||
![]() |
451bc2370a | ||
![]() |
0b17642c31 | ||
![]() |
214dc25576 | ||
![]() |
158eddfd44 | ||
![]() |
5daa6dbd25 | ||
![]() |
645ef3e61f | ||
![]() |
3be4b9d79b | ||
![]() |
5dcea51712 | ||
![]() |
6995968d50 | ||
![]() |
c4cb42f3c2 | ||
![]() |
0d4a7a2b3e | ||
![]() |
20cc9c9b42 | ||
![]() |
8a6bd04543 | ||
![]() |
263138a388 | ||
![]() |
e645342131 | ||
![]() |
6e4c707f9e | ||
![]() |
fca286d6c0 | ||
![]() |
5a2e08647f | ||
![]() |
f6dac98abd | ||
![]() |
ddb525f6cd | ||
![]() |
f7ee712456 | ||
![]() |
ff873e2f71 | ||
![]() |
54b57e6222 | ||
![]() |
375abfb95e | ||
![]() |
30a38fa6d1 | ||
![]() |
554c0b692d | ||
![]() |
61ac831882 | ||
![]() |
59e89a0daf | ||
![]() |
1e3950cd1d | ||
![]() |
f514ea453c | ||
![]() |
cc046478e5 | ||
![]() |
a17c1052cd | ||
![]() |
2408f9b8fa | ||
![]() |
6aae1b3378 | ||
![]() |
ed51223226 | ||
![]() |
013808b7f5 | ||
![]() |
af584e1d12 | ||
![]() |
3763d7a1d0 | ||
![]() |
ce92add096 | ||
![]() |
40c94b6596 | ||
![]() |
c894bc2e40 | ||
![]() |
415a4fa1af | ||
![]() |
b9367a33a8 | ||
![]() |
7170f06c08 | ||
![]() |
f2578a58b4 | ||
![]() |
1950656bd5 | ||
![]() |
eed3263c70 | ||
![]() |
02e01626f5 | ||
![]() |
41a2d9604e | ||
![]() |
7d6f188bfc | ||
![]() |
15a144f17a | ||
![]() |
c54f2b66da | ||
![]() |
685a0807d8 | ||
![]() |
0d404e0e37 | ||
![]() |
39bb859f57 | ||
![]() |
90e32b7e45 | ||
![]() |
63a2d9dd18 | ||
![]() |
4982693883 | ||
![]() |
f4211e3fa3 | ||
![]() |
eacf58b5a5 | ||
![]() |
f9349bc731 | ||
![]() |
3840671764 | ||
![]() |
fd62cf02d6 | ||
![]() |
254744cd7d | ||
![]() |
595d04c922 | ||
![]() |
a3969fe2c8 | ||
![]() |
220e4134b7 | ||
![]() |
56e176a6f1 | ||
![]() |
780c15d6b3 | ||
![]() |
55ff848b78 | ||
![]() |
dbe829bc7d | ||
![]() |
8d0508f320 | ||
![]() |
2741bb8b38 | ||
![]() |
16cadd53cf | ||
![]() |
a8d21c6112 | ||
![]() |
6b2e707653 | ||
![]() |
205b7451fa | ||
![]() |
1d3aeec0de | ||
![]() |
ac911dcd31 | ||
![]() |
89a94b3efc | ||
![]() |
71793dcfa5 | ||
![]() |
1e527a8350 | ||
![]() |
262b12eb93 | ||
![]() |
7fb1e699ae | ||
![]() |
9ee647329b | ||
![]() |
cd6dcec644 | ||
![]() |
d8f248c60e | ||
![]() |
2925b930ad | ||
![]() |
127aaba47b | ||
![]() |
8bc8761af6 | ||
![]() |
a88321d243 | ||
![]() |
4e19232960 | ||
![]() |
5b95bdb6b7 | ||
![]() |
0fc59ccb16 | ||
![]() |
a9daf9835a | ||
![]() |
2110d9c3b9 | ||
![]() |
b77e0b8125 | ||
![]() |
5197f102ea | ||
![]() |
447d4604c6 | ||
![]() |
5a84e34f93 | ||
![]() |
fb6d3cccdc | ||
![]() |
fad3cb185b | ||
![]() |
f61ce395f5 | ||
![]() |
17f3299152 | ||
![]() |
17e04589d0 | ||
![]() |
4b2edde81b | ||
![]() |
5d3d766f56 | ||
![]() |
94e2a0dea0 | ||
![]() |
21fe68add0 | ||
![]() |
af6ebea4a3 | ||
![]() |
3c17ee03b6 | ||
![]() |
0c3c007faf | ||
![]() |
330eb0957b | ||
![]() |
02923475e6 | ||
![]() |
01ff97b366 |
@@ -1,80 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["airbnb-base", "prettier"],
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": "2020",
|
|
||||||
"ecmaFeatures": {
|
|
||||||
"jsx": true,
|
|
||||||
"modules": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"react": {
|
|
||||||
"pragma": "h",
|
|
||||||
"version": "15.0"
|
|
||||||
},
|
|
||||||
"import/resolver": {
|
|
||||||
"webpack": {
|
|
||||||
"config": "webpack.config.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"__DEV__": false,
|
|
||||||
"__DEMO__": false,
|
|
||||||
"__BUILD__": false,
|
|
||||||
"__VERSION__": false,
|
|
||||||
"__STATIC_PATH__": false,
|
|
||||||
"Polymer": true,
|
|
||||||
"webkitSpeechRecognition": false,
|
|
||||||
"ResizeObserver": false
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"mocha": true
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"class-methods-use-this": 0,
|
|
||||||
"new-cap": 0,
|
|
||||||
"prefer-template": 0,
|
|
||||||
"object-shorthand": 0,
|
|
||||||
"func-names": 0,
|
|
||||||
"prefer-arrow-callback": 0,
|
|
||||||
"no-underscore-dangle": 0,
|
|
||||||
"no-var": 0,
|
|
||||||
"strict": 0,
|
|
||||||
"prefer-spread": 0,
|
|
||||||
"no-plusplus": 0,
|
|
||||||
"no-bitwise": 0,
|
|
||||||
"comma-dangle": 0,
|
|
||||||
"vars-on-top": 0,
|
|
||||||
"no-continue": 0,
|
|
||||||
"no-param-reassign": 0,
|
|
||||||
"no-multi-assign": 0,
|
|
||||||
"radix": 0,
|
|
||||||
"no-alert": 0,
|
|
||||||
"no-return-await": 0,
|
|
||||||
"prefer-destructuring": 0,
|
|
||||||
"no-restricted-globals": [2, "event"],
|
|
||||||
"prefer-promise-reject-errors": 0,
|
|
||||||
"import/prefer-default-export": 0,
|
|
||||||
"import/no-unresolved": 0,
|
|
||||||
"import/extensions": [2, "ignorePackages"],
|
|
||||||
"object-curly-newline": 0,
|
|
||||||
"default-case": 0,
|
|
||||||
"react/jsx-no-bind": [2, { "ignoreRefs": true }],
|
|
||||||
"react/jsx-no-duplicate-props": 2,
|
|
||||||
"react/self-closing-comp": 2,
|
|
||||||
"react/prefer-es6-class": 2,
|
|
||||||
"react/no-string-refs": 2,
|
|
||||||
"react/require-render-return": 2,
|
|
||||||
"react/no-find-dom-node": 2,
|
|
||||||
"react/no-is-mounted": 2,
|
|
||||||
"react/jsx-no-comment-textnodes": 2,
|
|
||||||
"react/jsx-no-undef": 2,
|
|
||||||
"react/jsx-uses-react": 2,
|
|
||||||
"react/jsx-uses-vars": 2,
|
|
||||||
"no-restricted-syntax": [0, "ForOfStatement"],
|
|
||||||
"prettier/prettier": "error"
|
|
||||||
},
|
|
||||||
"plugins": ["react", "prettier"]
|
|
||||||
}
|
|
@@ -1,12 +1,88 @@
|
|||||||
{
|
{
|
||||||
"extends": "./.eslintrc-hound.json",
|
"extends": [
|
||||||
"plugins": ["react"],
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"airbnb-typescript/base",
|
||||||
|
"plugin:wc/recommended",
|
||||||
|
"plugin:lit/recommended",
|
||||||
|
"prettier",
|
||||||
|
"prettier/@typescript-eslint"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2020,
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"modules": true
|
||||||
|
},
|
||||||
|
"sourceType": "module",
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"import/resolver": {
|
||||||
|
"webpack": {
|
||||||
|
"config": "./webpack.config.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"__DEV__": false,
|
||||||
|
"__DEMO__": false,
|
||||||
|
"__BUILD__": false,
|
||||||
|
"__VERSION__": false,
|
||||||
|
"__STATIC_PATH__": false,
|
||||||
|
"Polymer": true,
|
||||||
|
"webkitSpeechRecognition": false,
|
||||||
|
"ResizeObserver": false
|
||||||
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true
|
"browser": true,
|
||||||
|
"es6": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"import/no-unresolved": 2,
|
"class-methods-use-this": 0,
|
||||||
"linebreak-style": 0,
|
"new-cap": 0,
|
||||||
"implicit-arrow-linebreak": 0
|
"prefer-template": 0,
|
||||||
}
|
"object-shorthand": 0,
|
||||||
|
"func-names": 0,
|
||||||
|
"prefer-arrow-callback": 0,
|
||||||
|
"no-underscore-dangle": 0,
|
||||||
|
"no-var": 0,
|
||||||
|
"strict": 0,
|
||||||
|
"prefer-spread": 0,
|
||||||
|
"no-plusplus": 0,
|
||||||
|
"no-bitwise": 0,
|
||||||
|
"comma-dangle": 0,
|
||||||
|
"vars-on-top": 0,
|
||||||
|
"no-continue": 0,
|
||||||
|
"no-param-reassign": 0,
|
||||||
|
"no-multi-assign": 0,
|
||||||
|
"radix": 0,
|
||||||
|
"no-alert": 0,
|
||||||
|
"no-return-await": 0,
|
||||||
|
"no-nested-ternary": 0,
|
||||||
|
"prefer-destructuring": 0,
|
||||||
|
"no-restricted-globals": [2, "event"],
|
||||||
|
"prefer-promise-reject-errors": 0,
|
||||||
|
"import/order": 0,
|
||||||
|
"import/prefer-default-export": 0,
|
||||||
|
"import/no-unresolved": 0,
|
||||||
|
"import/no-cycle": 0,
|
||||||
|
"import/extensions": [
|
||||||
|
2,
|
||||||
|
"ignorePackages",
|
||||||
|
{ "ts": "ignorePackages", "js": "ignorePackages" }
|
||||||
|
],
|
||||||
|
"no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"],
|
||||||
|
"object-curly-newline": 0,
|
||||||
|
"default-case": 0,
|
||||||
|
"wc/no-self-class": 0,
|
||||||
|
"@typescript-eslint/camelcase": 0,
|
||||||
|
"@typescript-eslint/ban-ts-ignore": 0,
|
||||||
|
"@typescript-eslint/no-use-before-define": 0,
|
||||||
|
"@typescript-eslint/no-non-null-assertion": 0,
|
||||||
|
"@typescript-eslint/no-explicit-any": 0,
|
||||||
|
"@typescript-eslint/no-unused-vars": 0,
|
||||||
|
"@typescript-eslint/explicit-function-return-type": 0
|
||||||
|
},
|
||||||
|
"plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"],
|
||||||
|
"processor": "disable/disable"
|
||||||
}
|
}
|
||||||
|
12
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
@@ -62,6 +62,18 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
|
|||||||
- Browser and browser version:
|
- Browser and browser version:
|
||||||
- Operating system:
|
- Operating system:
|
||||||
|
|
||||||
|
## State of relevant entities
|
||||||
|
|
||||||
|
<!--
|
||||||
|
If your issue is about how an entity is shown in the UI, please add the state
|
||||||
|
and attributes for all situations with a screenshot of the UI.
|
||||||
|
You can find this information at `/developer-tools/state`
|
||||||
|
-->
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Problem-relevant configuration
|
## Problem-relevant configuration
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
9
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
@@ -3,23 +3,24 @@ name: Request a feature for the UI, Frontend or Lovelace
|
|||||||
about: Request an new feature for the Home Assistant frontend.
|
about: Request an new feature for the Home Assistant frontend.
|
||||||
labels: feature request
|
labels: feature request
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
DO NOT DELETE ANY TEXT from this template!
|
DO NOT DELETE ANY TEXT from this template!
|
||||||
Otherwise, your request may be closed without comment.
|
Otherwise, your request may be closed without comment.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## The request
|
## The request
|
||||||
<!--
|
|
||||||
|
<!--
|
||||||
Describe to our maintainers, the feature you would like to be added.
|
Describe to our maintainers, the feature you would like to be added.
|
||||||
Please be clear and concise and, if possible, provide a screenshot or mockup.
|
Please be clear and concise and, if possible, provide a screenshot or mockup.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
## The alternatives
|
## The alternatives
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Are you currently using, or have you considered alternatives?
|
Are you currently using, or have you considered alternatives?
|
||||||
If so, could you please describe those?
|
If so, could you please describe those?
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
## Additional information
|
## Additional information
|
||||||
|
|
||||||
|
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,7 +2,9 @@
|
|||||||
You are amazing! Thanks for contributing to our project!
|
You are amazing! Thanks for contributing to our project!
|
||||||
Please, DO NOT DELETE ANY TEXT from this template! (unless instructed).
|
Please, DO NOT DELETE ANY TEXT from this template! (unless instructed).
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Breaking change
|
## Breaking change
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
If your PR contains a breaking change for existing users, it is important
|
If your PR contains a breaking change for existing users, it is important
|
||||||
to tell them what breaks, how to make it work again and why we did this.
|
to tell them what breaks, how to make it work again and why we did this.
|
||||||
@@ -11,20 +13,20 @@
|
|||||||
Note: Remove this section if this PR is NOT a breaking change.
|
Note: Remove this section if this PR is NOT a breaking change.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
## Proposed change
|
## Proposed change
|
||||||
<!--
|
|
||||||
|
<!--
|
||||||
Describe the big picture of your changes here to communicate to the
|
Describe the big picture of your changes here to communicate to the
|
||||||
maintainers why we should accept this pull request. If it fixes a bug
|
maintainers why we should accept this pull request. If it fixes a bug
|
||||||
or resolves a feature request, be sure to link to that issue in the
|
or resolves a feature request, be sure to link to that issue in the
|
||||||
additional information section.
|
additional information section.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
## Type of change
|
## Type of change
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
What type of change does your PR introduce to the Home Assistant frontend?
|
What type of change does your PR introduce to the Home Assistant frontend?
|
||||||
NOTE: Please, check only 1! box!
|
NOTE: Please, check only 1! box!
|
||||||
If your PR requires multiple boxes to be checked, you'll most likely need to
|
If your PR requires multiple boxes to be checked, you'll most likely need to
|
||||||
split it into multiple PRs. This makes things easier and faster to code review.
|
split it into multiple PRs. This makes things easier and faster to code review.
|
||||||
-->
|
-->
|
||||||
@@ -36,6 +38,7 @@
|
|||||||
- [ ] Code quality improvements to existing code or addition of tests
|
- [ ] Code quality improvements to existing code or addition of tests
|
||||||
|
|
||||||
## Example configuration
|
## Example configuration
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Supplying a configuration snippet, makes it easier for a maintainer to test
|
Supplying a configuration snippet, makes it easier for a maintainer to test
|
||||||
your PR.
|
your PR.
|
||||||
@@ -46,16 +49,18 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Additional information
|
## Additional information
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Details are important, and help maintainers processing your PR.
|
Details are important, and help maintainers processing your PR.
|
||||||
Please be sure to fill out additional details, if applicable.
|
Please be sure to fill out additional details, if applicable.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
- This PR fixes or closes issue: fixes #
|
- This PR fixes or closes issue: fixes #
|
||||||
- This PR is related to issue:
|
- This PR is related to issue:
|
||||||
- Link to documentation pull request:
|
- Link to documentation pull request:
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Put an `x` in the boxes that apply. You can also fill these out after
|
Put an `x` in the boxes that apply. You can also fill these out after
|
||||||
creating the PR. If you're unsure about any of them, don't hesitate to ask.
|
creating the PR. If you're unsure about any of them, don't hesitate to ask.
|
||||||
@@ -74,4 +79,5 @@ If user exposed functionality or configuration variables are added/changed:
|
|||||||
<!--
|
<!--
|
||||||
Thank you for contributing <3
|
Thank you for contributing <3
|
||||||
-->
|
-->
|
||||||
|
|
||||||
[docs-repository]: https://github.com/home-assistant/home-assistant.io
|
[docs-repository]: https://github.com/home-assistant/home-assistant.io
|
||||||
|
2
.github/lock.yml
vendored
@@ -24,4 +24,4 @@ only: pulls
|
|||||||
|
|
||||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
# Optionally, specify configuration settings just for `issues` or `pulls`
|
||||||
issues:
|
issues:
|
||||||
daysUntilLock: 30
|
daysUntilLock: 30
|
||||||
|
10
.github/workflows/ci.yaml
vendored
@@ -35,13 +35,11 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
- name: Build icons
|
- name: Build icons
|
||||||
run: ./node_modules/.bin/gulp gen-icons-hassio gen-icons-mdi gen-icons-app
|
run: ./node_modules/.bin/gulp gen-icons-json
|
||||||
- name: Build translations
|
- name: Build translations
|
||||||
run: ./node_modules/.bin/gulp build-translations
|
run: ./node_modules/.bin/gulp build-translations
|
||||||
- name: Run eslint
|
- name: Run eslint
|
||||||
run: ./node_modules/.bin/eslint src hassio/src gallery/src
|
run: ./node_modules/.bin/eslint '{**/src,src}/**/*.{js,ts,html}' --ignore-path .gitignore
|
||||||
- name: Run tslint
|
|
||||||
run: ./node_modules/.bin/tslint 'src/**/*.ts' 'hassio/src/**/*.ts' 'gallery/src/**/*.ts' 'cast/src/**/*.ts' 'test-mocha/**/*.ts'
|
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
run: ./node_modules/.bin/tsc
|
run: ./node_modules/.bin/tsc
|
||||||
test:
|
test:
|
||||||
@@ -96,7 +94,7 @@ jobs:
|
|||||||
- name: Build Application
|
- name: Build Application
|
||||||
run: ./node_modules/.bin/gulp build-app
|
run: ./node_modules/.bin/gulp build-app
|
||||||
env:
|
env:
|
||||||
TRAVIS: "true"
|
IS_TEST: "true"
|
||||||
supervisor:
|
supervisor:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [lint, test]
|
needs: [lint, test]
|
||||||
@@ -124,4 +122,4 @@ jobs:
|
|||||||
- name: Build Application
|
- name: Build Application
|
||||||
run: ./node_modules/.bin/gulp build-hassio
|
run: ./node_modules/.bin/gulp build-hassio
|
||||||
env:
|
env:
|
||||||
TRAVIS: "true"
|
IS_TEST: "true"
|
||||||
|
4
.gitignore
vendored
@@ -5,7 +5,6 @@ npm-debug.log
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
hass_frontend/*
|
hass_frontend/*
|
||||||
.reify-cache
|
.reify-cache
|
||||||
demo/hademo-icons.html
|
|
||||||
|
|
||||||
# Python stuff
|
# Python stuff
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
@@ -31,3 +30,6 @@ src/cast/dev_const.ts
|
|||||||
# Secrets
|
# Secrets
|
||||||
.lokalise_token
|
.lokalise_token
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
|
|
||||||
|
#asdf
|
||||||
|
.tool-versions
|
||||||
|
10
.prettierignore
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
build
|
||||||
|
build-translations/*
|
||||||
|
translations/*
|
||||||
|
node_modules/*
|
||||||
|
hass_frontend/*
|
||||||
|
pip-selfcheck.json
|
||||||
|
|
||||||
|
# vscode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
1
.vscode/extensions.json
vendored
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"ms-vscode.vscode-typescript-tslint-plugin",
|
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"bierner.lit-html",
|
"bierner.lit-html",
|
||||||
"runem.lit-plugin"
|
"runem.lit-plugin"
|
||||||
|
@@ -8,7 +8,7 @@ schedules:
|
|||||||
branches:
|
branches:
|
||||||
include:
|
include:
|
||||||
- dev
|
- dev
|
||||||
always: false
|
always: true
|
||||||
variables:
|
variables:
|
||||||
- group: netlify
|
- group: netlify
|
||||||
|
|
||||||
@@ -24,4 +24,7 @@ jobs:
|
|||||||
|
|
||||||
# Demo
|
# Demo
|
||||||
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_DEMO}
|
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_DEMO}
|
||||||
|
|
||||||
|
# Gallery
|
||||||
|
curl -X POST -d {} https://api.netlify.com/build_hooks/${NETLIFY_GALLERY}
|
||||||
displayName: 'Trigger netlify build preview'
|
displayName: 'Trigger netlify build preview'
|
||||||
|
@@ -8,7 +8,7 @@ trigger:
|
|||||||
pr: none
|
pr: none
|
||||||
variables:
|
variables:
|
||||||
- name: versionWheels
|
- name: versionWheels
|
||||||
value: '1.3-3.7-alpine3.10'
|
value: '1.10.1-3.7-alpine3.11'
|
||||||
- name: versionNode
|
- name: versionNode
|
||||||
value: '12.1'
|
value: '12.1'
|
||||||
- group: twine
|
- group: twine
|
||||||
@@ -47,18 +47,13 @@ stages:
|
|||||||
|
|
||||||
script/release
|
script/release
|
||||||
displayName: "Build and release package"
|
displayName: "Build and release package"
|
||||||
|
- stage: "Wheels"
|
||||||
|
jobs:
|
||||||
- template: templates/azp-job-wheels.yaml@azure
|
- template: templates/azp-job-wheels.yaml@azure
|
||||||
parameters:
|
parameters:
|
||||||
builderVersion: '$(versionWheels)'
|
builderVersion: '$(versionWheels)'
|
||||||
builderApk: 'build-base'
|
wheelsRequirement: 'requirement.txt'
|
||||||
wheelsLocal: true
|
|
||||||
preBuild:
|
preBuild:
|
||||||
- task: NodeTool@0
|
|
||||||
displayName: "Use Node $(versionNode)"
|
|
||||||
inputs:
|
|
||||||
versionSpec: "$(versionNode)"
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
sleep 240
|
||||||
|
echo "home-assistant-frontend==$(Build.SourceBranchName)" > requirement.txt
|
||||||
yarn install
|
|
||||||
script/build_frontend
|
|
||||||
|
@@ -1,50 +1,40 @@
|
|||||||
|
const options = ({ latestBuild }) => ({
|
||||||
|
presets: [
|
||||||
|
!latestBuild && [require("@babel/preset-env").default, { modules: false }],
|
||||||
|
require("@babel/preset-typescript").default,
|
||||||
|
].filter(Boolean),
|
||||||
|
plugins: [
|
||||||
|
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
||||||
|
[
|
||||||
|
"@babel/plugin-proposal-object-rest-spread",
|
||||||
|
{ loose: true, useBuiltIns: true },
|
||||||
|
],
|
||||||
|
// Only support the syntax, Webpack will handle it.
|
||||||
|
"@babel/syntax-dynamic-import",
|
||||||
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||||
|
[
|
||||||
|
require("@babel/plugin-proposal-decorators").default,
|
||||||
|
{ decoratorsBeforeExport: true },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
require("@babel/plugin-proposal-class-properties").default,
|
||||||
|
{ loose: true },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports.options = options;
|
||||||
module.exports.babelLoaderConfig = ({ latestBuild }) => {
|
module.exports.babelLoaderConfig = ({ latestBuild }) => {
|
||||||
if (latestBuild === undefined) {
|
if (latestBuild === undefined) {
|
||||||
throw Error("latestBuild not defined for babel loader config");
|
throw Error("latestBuild not defined for babel loader config");
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
test: /\.m?js$|\.tsx?$/,
|
test: /\.m?js$|\.tsx?$/,
|
||||||
|
exclude: [require.resolve("@mdi/js/mdi.js"), require.resolve("hls.js")],
|
||||||
use: {
|
use: {
|
||||||
loader: "babel-loader",
|
loader: "babel-loader",
|
||||||
options: {
|
options: options({ latestBuild }),
|
||||||
presets: [
|
|
||||||
!latestBuild && [
|
|
||||||
require("@babel/preset-env").default,
|
|
||||||
{ modules: false },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
require("@babel/preset-typescript").default,
|
|
||||||
{
|
|
||||||
jsxPragma: "h",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
].filter(Boolean),
|
|
||||||
plugins: [
|
|
||||||
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
|
||||||
[
|
|
||||||
"@babel/plugin-proposal-object-rest-spread",
|
|
||||||
{ loose: true, useBuiltIns: true },
|
|
||||||
],
|
|
||||||
// Only support the syntax, Webpack will handle it.
|
|
||||||
"@babel/syntax-dynamic-import",
|
|
||||||
[
|
|
||||||
"@babel/transform-react-jsx",
|
|
||||||
{
|
|
||||||
pragma: "h",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"@babel/plugin-proposal-optional-chaining",
|
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
|
||||||
[
|
|
||||||
require("@babel/plugin-proposal-decorators").default,
|
|
||||||
{ decoratorsBeforeExport: true },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
require("@babel/plugin-proposal-class-properties").default,
|
|
||||||
{ loose: true },
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -1,6 +1,27 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const paths = require("./paths.js");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isProdBuild: process.env.NODE_ENV === "production",
|
isProdBuild() {
|
||||||
isStatsBuild: process.env.STATS === "1",
|
return process.env.NODE_ENV === "production";
|
||||||
isTravis: process.env.TRAVIS === "true",
|
},
|
||||||
isNetlify: process.env.NETLIFY === "true",
|
isStatsBuild() {
|
||||||
|
return process.env.STATS === "1";
|
||||||
|
},
|
||||||
|
isTest() {
|
||||||
|
return process.env.IS_TEST === "true";
|
||||||
|
},
|
||||||
|
isNetlify() {
|
||||||
|
return process.env.NETLIFY === "true";
|
||||||
|
},
|
||||||
|
version() {
|
||||||
|
const version = fs
|
||||||
|
.readFileSync(path.resolve(paths.polymer_dir, "setup.py"), "utf8")
|
||||||
|
.match(/\d{8}\.\d+/);
|
||||||
|
if (!version) {
|
||||||
|
throw Error("Version not found");
|
||||||
|
}
|
||||||
|
return version[0];
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@@ -5,7 +5,7 @@ const envVars = require("../env");
|
|||||||
|
|
||||||
require("./clean.js");
|
require("./clean.js");
|
||||||
require("./translations.js");
|
require("./translations.js");
|
||||||
require("./gen-icons.js");
|
require("./gen-icons-json.js");
|
||||||
require("./gather-static.js");
|
require("./gather-static.js");
|
||||||
require("./compress.js");
|
require("./compress.js");
|
||||||
require("./webpack.js");
|
require("./webpack.js");
|
||||||
@@ -21,7 +21,7 @@ gulp.task(
|
|||||||
"clean",
|
"clean",
|
||||||
gulp.parallel(
|
gulp.parallel(
|
||||||
"gen-service-worker-dev",
|
"gen-service-worker-dev",
|
||||||
gulp.parallel("gen-icons-app", "gen-icons-mdi"),
|
"gen-icons-json",
|
||||||
"gen-pages-dev",
|
"gen-pages-dev",
|
||||||
"gen-index-app-dev",
|
"gen-index-app-dev",
|
||||||
"build-translations"
|
"build-translations"
|
||||||
@@ -38,11 +38,11 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "production";
|
process.env.NODE_ENV = "production";
|
||||||
},
|
},
|
||||||
"clean",
|
"clean",
|
||||||
gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"copy-static",
|
"copy-static",
|
||||||
"webpack-prod-app",
|
"webpack-prod-app",
|
||||||
...// Don't compress running tests
|
...// Don't compress running tests
|
||||||
(envVars.isTravis ? [] : ["compress-app"]),
|
(envVars.isTest() ? [] : ["compress-app"]),
|
||||||
gulp.parallel(
|
gulp.parallel(
|
||||||
"gen-pages-prod",
|
"gen-pages-prod",
|
||||||
"gen-index-app-prod",
|
"gen-index-app-prod",
|
||||||
|
@@ -2,7 +2,6 @@ const gulp = require("gulp");
|
|||||||
|
|
||||||
require("./clean.js");
|
require("./clean.js");
|
||||||
require("./translations.js");
|
require("./translations.js");
|
||||||
require("./gen-icons.js");
|
|
||||||
require("./gather-static.js");
|
require("./gather-static.js");
|
||||||
require("./webpack.js");
|
require("./webpack.js");
|
||||||
require("./service-worker.js");
|
require("./service-worker.js");
|
||||||
@@ -15,12 +14,8 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "development";
|
process.env.NODE_ENV = "development";
|
||||||
},
|
},
|
||||||
"clean-cast",
|
"clean-cast",
|
||||||
gulp.parallel(
|
"translations-enable-merge-backend",
|
||||||
"gen-icons-app",
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"gen-icons-mdi",
|
|
||||||
"gen-index-cast-dev",
|
|
||||||
"build-translations"
|
|
||||||
),
|
|
||||||
"copy-static-cast",
|
"copy-static-cast",
|
||||||
"webpack-dev-server-cast"
|
"webpack-dev-server-cast"
|
||||||
)
|
)
|
||||||
@@ -33,7 +28,8 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "production";
|
process.env.NODE_ENV = "production";
|
||||||
},
|
},
|
||||||
"clean-cast",
|
"clean-cast",
|
||||||
gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
|
"translations-enable-merge-backend",
|
||||||
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"copy-static-cast",
|
"copy-static-cast",
|
||||||
"webpack-prod-cast",
|
"webpack-prod-cast",
|
||||||
"gen-index-cast-prod"
|
"gen-index-cast-prod"
|
||||||
|
@@ -3,7 +3,7 @@ const gulp = require("gulp");
|
|||||||
|
|
||||||
require("./clean.js");
|
require("./clean.js");
|
||||||
require("./translations.js");
|
require("./translations.js");
|
||||||
require("./gen-icons.js");
|
require("./gen-icons-json.js");
|
||||||
require("./gather-static.js");
|
require("./gather-static.js");
|
||||||
require("./webpack.js");
|
require("./webpack.js");
|
||||||
require("./service-worker.js");
|
require("./service-worker.js");
|
||||||
@@ -16,13 +16,8 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "development";
|
process.env.NODE_ENV = "development";
|
||||||
},
|
},
|
||||||
"clean-demo",
|
"clean-demo",
|
||||||
gulp.parallel(
|
"translations-enable-merge-backend",
|
||||||
"gen-icons-app",
|
gulp.parallel("gen-icons-json", "gen-index-demo-dev", "build-translations"),
|
||||||
"gen-icons-mdi",
|
|
||||||
"gen-icons-demo",
|
|
||||||
"gen-index-demo-dev",
|
|
||||||
"build-translations"
|
|
||||||
),
|
|
||||||
"copy-static-demo",
|
"copy-static-demo",
|
||||||
"webpack-dev-server-demo"
|
"webpack-dev-server-demo"
|
||||||
)
|
)
|
||||||
@@ -35,12 +30,9 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "production";
|
process.env.NODE_ENV = "production";
|
||||||
},
|
},
|
||||||
"clean-demo",
|
"clean-demo",
|
||||||
gulp.parallel(
|
// Cast needs to be backwards compatible and older HA has no translations
|
||||||
"gen-icons-app",
|
"translations-enable-merge-backend",
|
||||||
"gen-icons-mdi",
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"gen-icons-demo",
|
|
||||||
"build-translations"
|
|
||||||
),
|
|
||||||
"copy-static-demo",
|
"copy-static-demo",
|
||||||
"webpack-prod-demo",
|
"webpack-prod-demo",
|
||||||
"gen-index-demo-prod"
|
"gen-index-demo-prod"
|
||||||
|
@@ -2,7 +2,7 @@ const del = require("del");
|
|||||||
const gulp = require("gulp");
|
const gulp = require("gulp");
|
||||||
const mapStream = require("map-stream");
|
const mapStream = require("map-stream");
|
||||||
|
|
||||||
const inDir = "translations";
|
const inDir = "translations/frontend";
|
||||||
const downloadDir = inDir + "/downloads";
|
const downloadDir = inDir + "/downloads";
|
||||||
|
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
@@ -12,7 +12,7 @@ function hasHtml(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function recursiveCheckHasHtml(file, data, errors, recKey) {
|
function recursiveCheckHasHtml(file, data, errors, recKey) {
|
||||||
Object.keys(data).forEach(function(key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
if (typeof data[key] === "object") {
|
if (typeof data[key] === "object") {
|
||||||
const nextRecKey = recKey ? `${recKey}.${key}` : key;
|
const nextRecKey = recKey ? `${recKey}.${key}` : key;
|
||||||
recursiveCheckHasHtml(file, data[key], errors, nextRecKey);
|
recursiveCheckHasHtml(file, data[key], errors, nextRecKey);
|
||||||
@@ -25,7 +25,7 @@ function recursiveCheckHasHtml(file, data, errors, recKey) {
|
|||||||
function checkHtml() {
|
function checkHtml() {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
return mapStream(function(file, cb) {
|
return mapStream(function (file, cb) {
|
||||||
const content = file.contents;
|
const content = file.contents;
|
||||||
let error;
|
let error;
|
||||||
if (content) {
|
if (content) {
|
||||||
@@ -42,19 +42,19 @@ function checkHtml() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let taskName = "clean-downloaded-translations";
|
let taskName = "clean-downloaded-translations";
|
||||||
gulp.task(taskName, function() {
|
gulp.task(taskName, function () {
|
||||||
return del([`${downloadDir}/**`]);
|
return del([`${downloadDir}/**`]);
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|
||||||
taskName = "check-translations-html";
|
taskName = "check-translations-html";
|
||||||
gulp.task(taskName, function() {
|
gulp.task(taskName, function () {
|
||||||
return gulp.src(`${downloadDir}/*.json`).pipe(checkHtml());
|
return gulp.src(`${downloadDir}/*.json`).pipe(checkHtml());
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
|
||||||
taskName = "move-downloaded-translations";
|
taskName = "move-downloaded-translations";
|
||||||
gulp.task(taskName, function() {
|
gulp.task(taskName, function () {
|
||||||
return gulp.src(`${downloadDir}/*.json`).pipe(gulp.dest(inDir));
|
return gulp.src(`${downloadDir}/*.json`).pipe(gulp.dest(inDir));
|
||||||
});
|
});
|
||||||
tasks.push(taskName);
|
tasks.push(taskName);
|
||||||
|
@@ -47,11 +47,9 @@ gulp.task("gen-pages-dev", (done) => {
|
|||||||
for (const page of PAGES) {
|
for (const page of PAGES) {
|
||||||
const content = renderTemplate(page, {
|
const content = renderTemplate(page, {
|
||||||
latestPageJS: `/frontend_latest/${page}.js`,
|
latestPageJS: `/frontend_latest/${page}.js`,
|
||||||
latestHassIconsJS: "/frontend_latest/hass-icons.js",
|
|
||||||
|
|
||||||
es5Compatibility: "/frontend_es5/compatibility.js",
|
es5Compatibility: "/frontend_es5/compatibility.js",
|
||||||
es5PageJS: `/frontend_es5/${page}.js`,
|
es5PageJS: `/frontend_es5/${page}.js`,
|
||||||
es5HassIconsJS: "/frontend_es5/hass-icons.js",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.outputFileSync(path.resolve(config.root, `${page}.html`), content);
|
fs.outputFileSync(path.resolve(config.root, `${page}.html`), content);
|
||||||
@@ -66,11 +64,9 @@ gulp.task("gen-pages-prod", (done) => {
|
|||||||
for (const page of PAGES) {
|
for (const page of PAGES) {
|
||||||
const content = renderTemplate(page, {
|
const content = renderTemplate(page, {
|
||||||
latestPageJS: latestManifest[`${page}.js`],
|
latestPageJS: latestManifest[`${page}.js`],
|
||||||
latestHassIconsJS: latestManifest["hass-icons.js"],
|
|
||||||
|
|
||||||
es5Compatibility: es5Manifest["compatibility.js"],
|
es5Compatibility: es5Manifest["compatibility.js"],
|
||||||
es5PageJS: es5Manifest[`${page}.js`],
|
es5PageJS: es5Manifest[`${page}.js`],
|
||||||
es5HassIconsJS: es5Manifest["hass-icons.js"],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.outputFileSync(
|
fs.outputFileSync(
|
||||||
@@ -88,13 +84,11 @@ gulp.task("gen-index-app-dev", (done) => {
|
|||||||
latestAppJS: "/frontend_latest/app.js",
|
latestAppJS: "/frontend_latest/app.js",
|
||||||
latestCoreJS: "/frontend_latest/core.js",
|
latestCoreJS: "/frontend_latest/core.js",
|
||||||
latestCustomPanelJS: "/frontend_latest/custom-panel.js",
|
latestCustomPanelJS: "/frontend_latest/custom-panel.js",
|
||||||
latestHassIconsJS: "/frontend_latest/hass-icons.js",
|
|
||||||
|
|
||||||
es5Compatibility: "/frontend_es5/compatibility.js",
|
es5Compatibility: "/frontend_es5/compatibility.js",
|
||||||
es5AppJS: "/frontend_es5/app.js",
|
es5AppJS: "/frontend_es5/app.js",
|
||||||
es5CoreJS: "/frontend_es5/core.js",
|
es5CoreJS: "/frontend_es5/core.js",
|
||||||
es5CustomPanelJS: "/frontend_es5/custom-panel.js",
|
es5CustomPanelJS: "/frontend_es5/custom-panel.js",
|
||||||
es5HassIconsJS: "/frontend_es5/hass-icons.js",
|
|
||||||
}).replace(/#THEMEC/g, "{{ theme_color }}");
|
}).replace(/#THEMEC/g, "{{ theme_color }}");
|
||||||
|
|
||||||
fs.outputFileSync(path.resolve(config.root, "index.html"), content);
|
fs.outputFileSync(path.resolve(config.root, "index.html"), content);
|
||||||
@@ -108,13 +102,11 @@ gulp.task("gen-index-app-prod", (done) => {
|
|||||||
latestAppJS: latestManifest["app.js"],
|
latestAppJS: latestManifest["app.js"],
|
||||||
latestCoreJS: latestManifest["core.js"],
|
latestCoreJS: latestManifest["core.js"],
|
||||||
latestCustomPanelJS: latestManifest["custom-panel.js"],
|
latestCustomPanelJS: latestManifest["custom-panel.js"],
|
||||||
latestHassIconsJS: latestManifest["hass-icons.js"],
|
|
||||||
|
|
||||||
es5Compatibility: es5Manifest["compatibility.js"],
|
es5Compatibility: es5Manifest["compatibility.js"],
|
||||||
es5AppJS: es5Manifest["app.js"],
|
es5AppJS: es5Manifest["app.js"],
|
||||||
es5CoreJS: es5Manifest["core.js"],
|
es5CoreJS: es5Manifest["core.js"],
|
||||||
es5CustomPanelJS: es5Manifest["custom-panel.js"],
|
es5CustomPanelJS: es5Manifest["custom-panel.js"],
|
||||||
es5HassIconsJS: es5Manifest["hass-icons.js"],
|
|
||||||
});
|
});
|
||||||
const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}");
|
const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}");
|
||||||
|
|
||||||
@@ -222,7 +214,7 @@ gulp.task("gen-index-gallery-dev", (done) => {
|
|||||||
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||||
// run webpack as last in watch mode, which blocks output.
|
// run webpack as last in watch mode, which blocks output.
|
||||||
const content = renderGalleryTemplate("index", {
|
const content = renderGalleryTemplate("index", {
|
||||||
latestGalleryJS: "./entrypoint.js",
|
latestGalleryJS: "./frontend_latest/entrypoint.js",
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.outputFileSync(path.resolve(config.gallery_root, "index.html"), content);
|
fs.outputFileSync(path.resolve(config.gallery_root, "index.html"), content);
|
||||||
|
@@ -3,7 +3,7 @@ const gulp = require("gulp");
|
|||||||
|
|
||||||
require("./clean.js");
|
require("./clean.js");
|
||||||
require("./translations.js");
|
require("./translations.js");
|
||||||
require("./gen-icons.js");
|
require("./gen-icons-json.js");
|
||||||
require("./gather-static.js");
|
require("./gather-static.js");
|
||||||
require("./webpack.js");
|
require("./webpack.js");
|
||||||
require("./service-worker.js");
|
require("./service-worker.js");
|
||||||
@@ -16,7 +16,8 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "development";
|
process.env.NODE_ENV = "development";
|
||||||
},
|
},
|
||||||
"clean-gallery",
|
"clean-gallery",
|
||||||
gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
|
"translations-enable-merge-backend",
|
||||||
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"copy-static-gallery",
|
"copy-static-gallery",
|
||||||
"gen-index-gallery-dev",
|
"gen-index-gallery-dev",
|
||||||
"webpack-dev-server-gallery"
|
"webpack-dev-server-gallery"
|
||||||
@@ -30,7 +31,8 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "production";
|
process.env.NODE_ENV = "production";
|
||||||
},
|
},
|
||||||
"clean-gallery",
|
"clean-gallery",
|
||||||
gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"),
|
"translations-enable-merge-backend",
|
||||||
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"copy-static-gallery",
|
"copy-static-gallery",
|
||||||
"webpack-prod-gallery",
|
"webpack-prod-gallery",
|
||||||
"gen-index-gallery-prod"
|
"gen-index-gallery-prod"
|
||||||
|
@@ -26,6 +26,13 @@ function copyTranslations(staticDir) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyMdiIcons(staticDir) {
|
||||||
|
const staticPath = genStaticPath(staticDir);
|
||||||
|
|
||||||
|
// MDI icons output
|
||||||
|
fs.copySync(polyPath("build/mdi"), staticPath("mdi"));
|
||||||
|
}
|
||||||
|
|
||||||
function copyPolyfills(staticDir) {
|
function copyPolyfills(staticDir) {
|
||||||
const staticPath = genStaticPath(staticDir);
|
const staticPath = genStaticPath(staticDir);
|
||||||
|
|
||||||
@@ -73,19 +80,15 @@ gulp.task("copy-translations", (done) => {
|
|||||||
|
|
||||||
gulp.task("copy-static", (done) => {
|
gulp.task("copy-static", (done) => {
|
||||||
const staticDir = paths.static;
|
const staticDir = paths.static;
|
||||||
const staticPath = genStaticPath(paths.static);
|
|
||||||
// Basic static files
|
// Basic static files
|
||||||
fs.copySync(polyPath("public"), paths.root);
|
fs.copySync(polyPath("public"), paths.root);
|
||||||
|
|
||||||
copyPolyfills(staticDir);
|
copyPolyfills(staticDir);
|
||||||
copyFonts(staticDir);
|
copyFonts(staticDir);
|
||||||
copyTranslations(staticDir);
|
copyTranslations(staticDir);
|
||||||
|
copyMdiIcons(staticDir);
|
||||||
|
|
||||||
// Panel assets
|
// Panel assets
|
||||||
copyFileDir(
|
|
||||||
npmPath("react-big-calendar/lib/css/react-big-calendar.css"),
|
|
||||||
staticPath("panels/calendar/")
|
|
||||||
);
|
|
||||||
copyMapPanel(staticDir);
|
copyMapPanel(staticDir);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -103,6 +106,7 @@ gulp.task("copy-static-demo", (done) => {
|
|||||||
copyMapPanel(paths.demo_static);
|
copyMapPanel(paths.demo_static);
|
||||||
copyFonts(paths.demo_static);
|
copyFonts(paths.demo_static);
|
||||||
copyTranslations(paths.demo_static);
|
copyTranslations(paths.demo_static);
|
||||||
|
copyMdiIcons(paths.demo_static);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -115,6 +119,7 @@ gulp.task("copy-static-cast", (done) => {
|
|||||||
copyMapPanel(paths.cast_static);
|
copyMapPanel(paths.cast_static);
|
||||||
copyFonts(paths.cast_static);
|
copyFonts(paths.cast_static);
|
||||||
copyTranslations(paths.cast_static);
|
copyTranslations(paths.cast_static);
|
||||||
|
copyMdiIcons(paths.cast_static);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -127,5 +132,6 @@ gulp.task("copy-static-gallery", (done) => {
|
|||||||
copyMapPanel(paths.gallery_static);
|
copyMapPanel(paths.gallery_static);
|
||||||
copyFonts(paths.gallery_static);
|
copyFonts(paths.gallery_static);
|
||||||
copyTranslations(paths.gallery_static);
|
copyTranslations(paths.gallery_static);
|
||||||
|
copyMdiIcons(paths.gallery_static);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
112
build-scripts/gulp/gen-icons-json.js
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
const gulp = require("gulp");
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const hash = require("object-hash");
|
||||||
|
|
||||||
|
const ICON_PACKAGE_PATH = path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"../../node_modules/@mdi/svg/"
|
||||||
|
);
|
||||||
|
const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json");
|
||||||
|
const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json");
|
||||||
|
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
|
||||||
|
const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi");
|
||||||
|
|
||||||
|
const encoding = "utf8";
|
||||||
|
|
||||||
|
const getMeta = () => {
|
||||||
|
const file = fs.readFileSync(META_PATH, { encoding });
|
||||||
|
const meta = JSON.parse(file);
|
||||||
|
return meta.map((icon) => {
|
||||||
|
const svg = fs.readFileSync(`${ICON_PATH}/${icon.name}.svg`, {
|
||||||
|
encoding,
|
||||||
|
});
|
||||||
|
return { path: svg.match(/ d="([^"]+)"/)[1], name: icon.name };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const splitBySize = (meta) => {
|
||||||
|
const chunks = [];
|
||||||
|
const CHUNK_SIZE = 50000;
|
||||||
|
|
||||||
|
let curSize = 0;
|
||||||
|
let startKey;
|
||||||
|
let icons = [];
|
||||||
|
|
||||||
|
Object.values(meta).forEach((icon) => {
|
||||||
|
if (startKey === undefined) {
|
||||||
|
startKey = icon.name;
|
||||||
|
}
|
||||||
|
curSize += icon.path.length;
|
||||||
|
icons.push(icon);
|
||||||
|
if (curSize > CHUNK_SIZE) {
|
||||||
|
chunks.push({
|
||||||
|
startKey,
|
||||||
|
endKey: icon.name,
|
||||||
|
icons,
|
||||||
|
});
|
||||||
|
curSize = 0;
|
||||||
|
startKey = undefined;
|
||||||
|
icons = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
chunks.push({
|
||||||
|
startKey,
|
||||||
|
icons,
|
||||||
|
});
|
||||||
|
|
||||||
|
return chunks;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findDifferentiator = (curString, prevString) => {
|
||||||
|
for (let i = 0; i < curString.length; i++) {
|
||||||
|
if (curString[i] !== prevString[i]) {
|
||||||
|
return curString.substring(0, i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error("Cannot find differentiator", curString, prevString);
|
||||||
|
};
|
||||||
|
|
||||||
|
gulp.task("gen-icons-json", (done) => {
|
||||||
|
const meta = getMeta();
|
||||||
|
const split = splitBySize(meta);
|
||||||
|
|
||||||
|
if (!fs.existsSync(OUTPUT_DIR)) {
|
||||||
|
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
||||||
|
}
|
||||||
|
const parts = [];
|
||||||
|
|
||||||
|
let lastEnd;
|
||||||
|
split.forEach((chunk) => {
|
||||||
|
let startKey;
|
||||||
|
if (lastEnd === undefined) {
|
||||||
|
chunk.startKey = undefined;
|
||||||
|
startKey = undefined;
|
||||||
|
} else {
|
||||||
|
startKey = findDifferentiator(chunk.startKey, lastEnd);
|
||||||
|
}
|
||||||
|
lastEnd = chunk.endKey;
|
||||||
|
|
||||||
|
const output = {};
|
||||||
|
chunk.icons.forEach((icon) => {
|
||||||
|
output[icon.name] = icon.path;
|
||||||
|
});
|
||||||
|
const filename = hash(output);
|
||||||
|
parts.push({ start: startKey, file: filename });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.resolve(OUTPUT_DIR, `${filename}.json`),
|
||||||
|
JSON.stringify(output)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = fs.readFileSync(PACKAGE_PATH, { encoding });
|
||||||
|
const package = JSON.parse(file);
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.resolve(OUTPUT_DIR, "iconMetadata.json"),
|
||||||
|
JSON.stringify({ version: package.version, parts })
|
||||||
|
);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
@@ -1,127 +0,0 @@
|
|||||||
const gulp = require("gulp");
|
|
||||||
const path = require("path");
|
|
||||||
const fs = require("fs");
|
|
||||||
const paths = require("../paths");
|
|
||||||
const { mapFiles } = require("../util");
|
|
||||||
|
|
||||||
const ICON_PACKAGE_PATH = path.resolve(
|
|
||||||
__dirname,
|
|
||||||
"../../node_modules/@mdi/svg/"
|
|
||||||
);
|
|
||||||
const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json");
|
|
||||||
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
|
|
||||||
const OUTPUT_DIR = path.resolve(__dirname, "../../build");
|
|
||||||
const MDI_OUTPUT_PATH = path.resolve(OUTPUT_DIR, "mdi.html");
|
|
||||||
const HASS_OUTPUT_PATH = path.resolve(OUTPUT_DIR, "hass-icons.html");
|
|
||||||
|
|
||||||
const BUILT_IN_PANEL_ICONS = [
|
|
||||||
"calendar", // Calendar
|
|
||||||
"settings", // Config
|
|
||||||
"home-assistant", // Hass.io
|
|
||||||
"poll-box", // History panel
|
|
||||||
"format-list-bulleted-type", // Logbook
|
|
||||||
"mailbox", // Mailbox
|
|
||||||
"tooltip-account", // Map
|
|
||||||
"cart", // Shopping List
|
|
||||||
"hammer", // developer-tools
|
|
||||||
];
|
|
||||||
|
|
||||||
// Given an icon name, load the SVG file
|
|
||||||
function loadIcon(name) {
|
|
||||||
const iconPath = path.resolve(ICON_PATH, `${name}.svg`);
|
|
||||||
try {
|
|
||||||
return fs.readFileSync(iconPath, "utf-8");
|
|
||||||
} catch (err) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given an SVG file, convert it to an iron-iconset-svg definition
|
|
||||||
function transformXMLtoPolymer(name, xml) {
|
|
||||||
const start = xml.indexOf("><path") + 1;
|
|
||||||
const end = xml.length - start - 6;
|
|
||||||
const pth = xml.substr(start, end);
|
|
||||||
return `<g id="${name}">${pth}</g>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given an iconset name and icon names, generate a polymer iconset
|
|
||||||
function generateIconset(iconsetName, iconNames) {
|
|
||||||
const iconDefs = Array.from(iconNames)
|
|
||||||
.map((name) => {
|
|
||||||
const iconDef = loadIcon(name);
|
|
||||||
if (!iconDef) {
|
|
||||||
throw new Error(`Unknown icon referenced: ${name}`);
|
|
||||||
}
|
|
||||||
return transformXMLtoPolymer(name, iconDef);
|
|
||||||
})
|
|
||||||
.join("");
|
|
||||||
return `<ha-iconset-svg name="${iconsetName}" size="24"><svg><defs>${iconDefs}</defs></svg></ha-iconset-svg>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find all icons used by the project.
|
|
||||||
function findIcons(searchPath, iconsetName) {
|
|
||||||
const iconRegex = new RegExp(`${iconsetName}:[\\w-]+`, "g");
|
|
||||||
const icons = new Set();
|
|
||||||
function processFile(filename) {
|
|
||||||
const content = fs.readFileSync(filename);
|
|
||||||
let match;
|
|
||||||
// eslint-disable-next-line
|
|
||||||
while ((match = iconRegex.exec(content))) {
|
|
||||||
// strip off "hass:" and add to set
|
|
||||||
icons.add(match[0].substr(iconsetName.length + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mapFiles(searchPath, ".js", processFile);
|
|
||||||
mapFiles(searchPath, ".ts", processFile);
|
|
||||||
return icons;
|
|
||||||
}
|
|
||||||
|
|
||||||
gulp.task("gen-icons-mdi", (done) => {
|
|
||||||
const meta = JSON.parse(
|
|
||||||
fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), "UTF-8")
|
|
||||||
);
|
|
||||||
const iconNames = meta.map((iconInfo) => iconInfo.name);
|
|
||||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
||||||
fs.mkdirSync(OUTPUT_DIR);
|
|
||||||
}
|
|
||||||
fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset("mdi", iconNames));
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("gen-icons-app", (done) => {
|
|
||||||
const iconNames = findIcons("./src", "hass");
|
|
||||||
BUILT_IN_PANEL_ICONS.forEach((name) => iconNames.add(name));
|
|
||||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
||||||
fs.mkdirSync(OUTPUT_DIR);
|
|
||||||
}
|
|
||||||
fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset("hass", iconNames));
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("gen-icons-demo", (done) => {
|
|
||||||
const iconNames = findIcons(path.resolve(paths.demo_dir, "./src"), "hademo");
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.resolve(paths.demo_dir, "hademo-icons.html"),
|
|
||||||
generateIconset("hademo", iconNames)
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("gen-icons-hassio", (done) => {
|
|
||||||
const iconNames = findIcons(
|
|
||||||
path.resolve(paths.hassio_dir, "./src"),
|
|
||||||
"hassio"
|
|
||||||
);
|
|
||||||
// Find hassio icons inside HA main repo.
|
|
||||||
for (const item of findIcons(
|
|
||||||
path.resolve(paths.polymer_dir, "./src"),
|
|
||||||
"hassio"
|
|
||||||
)) {
|
|
||||||
iconNames.add(item);
|
|
||||||
}
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.resolve(paths.hassio_dir, "hassio-icons.html"),
|
|
||||||
generateIconset("hassio", iconNames)
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
@@ -3,7 +3,7 @@ const gulp = require("gulp");
|
|||||||
const envVars = require("../env");
|
const envVars = require("../env");
|
||||||
|
|
||||||
require("./clean.js");
|
require("./clean.js");
|
||||||
require("./gen-icons.js");
|
require("./gen-icons-json.js");
|
||||||
require("./webpack.js");
|
require("./webpack.js");
|
||||||
require("./compress.js");
|
require("./compress.js");
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "development";
|
process.env.NODE_ENV = "development";
|
||||||
},
|
},
|
||||||
"clean-hassio",
|
"clean-hassio",
|
||||||
gulp.parallel("gen-icons-hassio", "gen-icons-mdi"),
|
"gen-icons-json",
|
||||||
"webpack-watch-hassio"
|
"webpack-watch-hassio"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -26,9 +26,9 @@ gulp.task(
|
|||||||
process.env.NODE_ENV = "production";
|
process.env.NODE_ENV = "production";
|
||||||
},
|
},
|
||||||
"clean-hassio",
|
"clean-hassio",
|
||||||
gulp.parallel("gen-icons-hassio", "gen-icons-mdi"),
|
"gen-icons-json",
|
||||||
"webpack-prod-hassio",
|
"webpack-prod-hassio",
|
||||||
...// Don't compress running tests
|
...// Don't compress running tests
|
||||||
(envVars.isTravis ? [] : ["compress-hassio"])
|
(envVars.isTest() ? [] : ["compress-hassio"])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@@ -14,13 +14,20 @@ const { mapFiles } = require("../util");
|
|||||||
const env = require("../env");
|
const env = require("../env");
|
||||||
const paths = require("../paths");
|
const paths = require("../paths");
|
||||||
|
|
||||||
const inDir = "translations";
|
const inFrontendDir = "translations/frontend";
|
||||||
|
const inBackendDir = "translations/backend";
|
||||||
const workDir = "build-translations";
|
const workDir = "build-translations";
|
||||||
const fullDir = workDir + "/full";
|
const fullDir = workDir + "/full";
|
||||||
const coreDir = workDir + "/core";
|
const coreDir = workDir + "/core";
|
||||||
const outDir = workDir + "/output";
|
const outDir = workDir + "/output";
|
||||||
|
let mergeBackend = false;
|
||||||
|
|
||||||
String.prototype.rsplit = function(sep, maxsplit) {
|
gulp.task("translations-enable-merge-backend", (done) => {
|
||||||
|
mergeBackend = true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
String.prototype.rsplit = function (sep, maxsplit) {
|
||||||
var split = this.split(sep);
|
var split = this.split(sep);
|
||||||
return maxsplit
|
return maxsplit
|
||||||
? [split.slice(0, -maxsplit).join(sep)].concat(split.slice(-maxsplit))
|
? [split.slice(0, -maxsplit).join(sep)].concat(split.slice(-maxsplit))
|
||||||
@@ -45,7 +52,7 @@ const TRANSLATION_FRAGMENTS = [
|
|||||||
|
|
||||||
function recursiveFlatten(prefix, data) {
|
function recursiveFlatten(prefix, data) {
|
||||||
let output = {};
|
let output = {};
|
||||||
Object.keys(data).forEach(function(key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
if (typeof data[key] === "object") {
|
if (typeof data[key] === "object") {
|
||||||
output = {
|
output = {
|
||||||
...output,
|
...output,
|
||||||
@@ -107,7 +114,12 @@ function lokaliseTransform(data, original, file) {
|
|||||||
output[key] = lokaliseTransform(value, original, file);
|
output[key] = lokaliseTransform(value, original, file);
|
||||||
} else {
|
} else {
|
||||||
output[key] = value.replace(re_key_reference, (match, key) => {
|
output[key] = value.replace(re_key_reference, (match, key) => {
|
||||||
const replace = key.split("::").reduce((tr, k) => tr[k], original);
|
const replace = key.split("::").reduce((tr, k) => {
|
||||||
|
if (!tr) {
|
||||||
|
throw Error(`Invalid key placeholder ${key} in ${file.path}`);
|
||||||
|
}
|
||||||
|
return tr[k];
|
||||||
|
}, original);
|
||||||
if (typeof replace !== "string") {
|
if (typeof replace !== "string") {
|
||||||
throw Error(`Invalid key placeholder ${key} in ${file.path}`);
|
throw Error(`Invalid key placeholder ${key} in ${file.path}`);
|
||||||
}
|
}
|
||||||
@@ -118,7 +130,7 @@ function lokaliseTransform(data, original, file) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task("clean-translations", function() {
|
gulp.task("clean-translations", function () {
|
||||||
return del([workDir]);
|
return del([workDir]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -129,7 +141,7 @@ gulp.task("ensure-translations-build-dir", (done) => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("create-test-metadata", function(cb) {
|
gulp.task("create-test-metadata", function (cb) {
|
||||||
fs.writeFile(
|
fs.writeFile(
|
||||||
workDir + "/testMetadata.json",
|
workDir + "/testMetadata.json",
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@@ -147,7 +159,7 @@ gulp.task(
|
|||||||
return gulp
|
return gulp
|
||||||
.src(path.join(paths.translations_src, "en.json"))
|
.src(path.join(paths.translations_src, "en.json"))
|
||||||
.pipe(
|
.pipe(
|
||||||
transform(function(data, file) {
|
transform(function (data, file) {
|
||||||
return recursiveEmpty(data);
|
return recursiveEmpty(data);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -165,28 +177,40 @@ gulp.task(
|
|||||||
* project is buildable immediately after merging new translation keys, since
|
* project is buildable immediately after merging new translation keys, since
|
||||||
* the Lokalise update to translations/en.json will not happen immediately.
|
* the Lokalise update to translations/en.json will not happen immediately.
|
||||||
*/
|
*/
|
||||||
gulp.task("build-master-translation", function() {
|
gulp.task("build-master-translation", function () {
|
||||||
|
const src = [path.join(paths.translations_src, "en.json")];
|
||||||
|
|
||||||
|
if (mergeBackend) {
|
||||||
|
src.push(path.join(inBackendDir, "en.json"));
|
||||||
|
}
|
||||||
|
|
||||||
return gulp
|
return gulp
|
||||||
.src(path.join(paths.translations_src, "en.json"))
|
.src(src)
|
||||||
.pipe(
|
.pipe(
|
||||||
transform(function(data, file) {
|
transform(function (data, file) {
|
||||||
return lokaliseTransform(data, data, file);
|
return lokaliseTransform(data, data, file);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.pipe(rename("translationMaster.json"))
|
.pipe(
|
||||||
|
merge({
|
||||||
|
fileName: "translationMaster.json",
|
||||||
|
})
|
||||||
|
)
|
||||||
.pipe(gulp.dest(workDir));
|
.pipe(gulp.dest(workDir));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("build-merged-translations", function() {
|
gulp.task("build-merged-translations", function () {
|
||||||
return gulp
|
return gulp
|
||||||
.src([inDir + "/*.json", workDir + "/test.json"], { allowEmpty: true })
|
.src([inFrontendDir + "/*.json", workDir + "/test.json"], {
|
||||||
|
allowEmpty: true,
|
||||||
|
})
|
||||||
.pipe(
|
.pipe(
|
||||||
transform(function(data, file) {
|
transform(function (data, file) {
|
||||||
return lokaliseTransform(data, data, file);
|
return lokaliseTransform(data, data, file);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
foreach(function(stream, file) {
|
foreach(function (stream, file) {
|
||||||
// For each language generate a merged json file. It begins with the master
|
// For each language generate a merged json file. It begins with the master
|
||||||
// translation as a failsafe for untranslated strings, and merges all parent
|
// translation as a failsafe for untranslated strings, and merges all parent
|
||||||
// tags into one file for each specific subtag
|
// tags into one file for each specific subtag
|
||||||
@@ -202,7 +226,10 @@ gulp.task("build-merged-translations", function() {
|
|||||||
if (lang === "test") {
|
if (lang === "test") {
|
||||||
src.push(workDir + "/test.json");
|
src.push(workDir + "/test.json");
|
||||||
} else if (lang !== "en") {
|
} else if (lang !== "en") {
|
||||||
src.push(inDir + "/" + lang + ".json");
|
src.push(inFrontendDir + "/" + lang + ".json");
|
||||||
|
if (mergeBackend) {
|
||||||
|
src.push(inBackendDir + "/" + lang + ".json");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gulp
|
return gulp
|
||||||
@@ -223,7 +250,7 @@ var taskName;
|
|||||||
const splitTasks = [];
|
const splitTasks = [];
|
||||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||||
taskName = "build-translation-fragment-" + fragment;
|
taskName = "build-translation-fragment-" + fragment;
|
||||||
gulp.task(taskName, function() {
|
gulp.task(taskName, function () {
|
||||||
// Return only the translations for this fragment.
|
// Return only the translations for this fragment.
|
||||||
return gulp
|
return gulp
|
||||||
.src(fullDir + "/*.json")
|
.src(fullDir + "/*.json")
|
||||||
@@ -242,12 +269,12 @@ TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
taskName = "build-translation-core";
|
taskName = "build-translation-core";
|
||||||
gulp.task(taskName, function() {
|
gulp.task(taskName, function () {
|
||||||
// Remove the fragment translations from the core translation.
|
// Remove the fragment translations from the core translation.
|
||||||
return gulp
|
return gulp
|
||||||
.src(fullDir + "/*.json")
|
.src(fullDir + "/*.json")
|
||||||
.pipe(
|
.pipe(
|
||||||
transform((data) => {
|
transform((data, file) => {
|
||||||
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
TRANSLATION_FRAGMENTS.forEach((fragment) => {
|
||||||
delete data.ui.panel[fragment];
|
delete data.ui.panel[fragment];
|
||||||
});
|
});
|
||||||
@@ -259,7 +286,7 @@ gulp.task(taskName, function() {
|
|||||||
|
|
||||||
splitTasks.push(taskName);
|
splitTasks.push(taskName);
|
||||||
|
|
||||||
gulp.task("build-flattened-translations", function() {
|
gulp.task("build-flattened-translations", function () {
|
||||||
// Flatten the split versions of our translations, and move them into outDir
|
// Flatten the split versions of our translations, and move them into outDir
|
||||||
return gulp
|
return gulp
|
||||||
.src(
|
.src(
|
||||||
@@ -269,7 +296,7 @@ gulp.task("build-flattened-translations", function() {
|
|||||||
{ base: workDir }
|
{ base: workDir }
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
transform(function(data) {
|
transform(function (data) {
|
||||||
// Polymer.AppLocalizeBehavior requires flattened json
|
// Polymer.AppLocalizeBehavior requires flattened json
|
||||||
return flatten(data);
|
return flatten(data);
|
||||||
})
|
})
|
||||||
@@ -292,10 +319,11 @@ gulp.task(
|
|||||||
function fingerprintTranslationFiles() {
|
function fingerprintTranslationFiles() {
|
||||||
// Fingerprint full file of each language
|
// Fingerprint full file of each language
|
||||||
const files = fs.readdirSync(fullDir);
|
const files = fs.readdirSync(fullDir);
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
fingerprints[files[i].split(".")[0]] = {
|
fingerprints[files[i].split(".")[0]] = {
|
||||||
// In dev we create fake hashes
|
// In dev we create fake hashes
|
||||||
hash: env.isProdBuild
|
hash: env.isProdBuild()
|
||||||
? crypto
|
? crypto
|
||||||
.createHash("md5")
|
.createHash("md5")
|
||||||
.update(fs.readFileSync(path.join(fullDir, files[i]), "utf-8"))
|
.update(fs.readFileSync(path.join(fullDir, files[i]), "utf-8"))
|
||||||
@@ -332,7 +360,7 @@ gulp.task(
|
|||||||
gulp.series(
|
gulp.series(
|
||||||
"clean-translations",
|
"clean-translations",
|
||||||
"ensure-translations-build-dir",
|
"ensure-translations-build-dir",
|
||||||
env.isProdBuild ? (done) => done() : "create-test-translation",
|
env.isProdBuild() ? (done) => done() : "create-test-translation",
|
||||||
"build-master-translation",
|
"build-master-translation",
|
||||||
"build-merged-translations",
|
"build-merged-translations",
|
||||||
gulp.parallel(...splitTasks),
|
gulp.parallel(...splitTasks),
|
||||||
@@ -350,7 +378,7 @@ gulp.task(
|
|||||||
)
|
)
|
||||||
.pipe(merge({}))
|
.pipe(merge({}))
|
||||||
.pipe(
|
.pipe(
|
||||||
transform(function(data) {
|
transform(function (data) {
|
||||||
const newData = {};
|
const newData = {};
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
// Filter out translations without native name.
|
// Filter out translations without native name.
|
||||||
|
@@ -28,7 +28,7 @@ const runDevServer = ({
|
|||||||
open: true,
|
open: true,
|
||||||
watchContentBase: true,
|
watchContentBase: true,
|
||||||
contentBase,
|
contentBase,
|
||||||
}).listen(port, listenHost, function(err) {
|
}).listen(port, listenHost, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -150,9 +150,8 @@ gulp.task(
|
|||||||
|
|
||||||
gulp.task("webpack-dev-server-gallery", () => {
|
gulp.task("webpack-dev-server-gallery", () => {
|
||||||
runDevServer({
|
runDevServer({
|
||||||
compiler: webpack(
|
// We don't use the es5 build, but the dev server will fuck up the publicPath if we don't
|
||||||
createGalleryConfig({ latestBuild: true, isProdBuild: false })
|
compiler: webpack(bothBuilds(createGalleryConfig, { isProdBuild: false })),
|
||||||
),
|
|
||||||
contentBase: paths.gallery_root,
|
contentBase: paths.gallery_root,
|
||||||
port: 8100,
|
port: 8100,
|
||||||
});
|
});
|
||||||
|
@@ -1,20 +1,12 @@
|
|||||||
const webpack = require("webpack");
|
const webpack = require("webpack");
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
const WorkboxPlugin = require("workbox-webpack-plugin");
|
const WorkboxPlugin = require("workbox-webpack-plugin");
|
||||||
const ManifestPlugin = require("webpack-manifest-plugin");
|
const ManifestPlugin = require("webpack-manifest-plugin");
|
||||||
const paths = require("./paths.js");
|
const paths = require("./paths.js");
|
||||||
|
const env = require("./env.js");
|
||||||
const { babelLoaderConfig } = require("./babel.js");
|
const { babelLoaderConfig } = require("./babel.js");
|
||||||
|
|
||||||
let version = fs
|
|
||||||
.readFileSync(path.resolve(paths.polymer_dir, "setup.py"), "utf8")
|
|
||||||
.match(/\d{8}\.\d+/);
|
|
||||||
if (!version) {
|
|
||||||
throw Error("Version not found");
|
|
||||||
}
|
|
||||||
version = version[0];
|
|
||||||
|
|
||||||
const createWebpackConfig = ({
|
const createWebpackConfig = ({
|
||||||
entry,
|
entry,
|
||||||
outputRoot,
|
outputRoot,
|
||||||
@@ -38,17 +30,11 @@ const createWebpackConfig = ({
|
|||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: "raw-loader",
|
use: "raw-loader",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
test: /\.(html)$/,
|
|
||||||
use: {
|
|
||||||
loader: "html-loader",
|
|
||||||
options: {
|
|
||||||
exportAsEs6Default: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
externals: {
|
||||||
|
esprima: "esprima",
|
||||||
|
},
|
||||||
optimization: {
|
optimization: {
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new TerserPlugin({
|
new TerserPlugin({
|
||||||
@@ -68,8 +54,9 @@ const createWebpackConfig = ({
|
|||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
__DEV__: !isProdBuild,
|
__DEV__: !isProdBuild,
|
||||||
__BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
|
__BUILD__: JSON.stringify(latestBuild ? "latest" : "es5"),
|
||||||
__VERSION__: JSON.stringify(version),
|
__VERSION__: JSON.stringify(env.version()),
|
||||||
__DEMO__: false,
|
__DEMO__: false,
|
||||||
|
__BACKWARDS_COMPAT__: false,
|
||||||
__STATIC_PATH__: "/static/",
|
__STATIC_PATH__: "/static/",
|
||||||
"process.env.NODE_ENV": JSON.stringify(
|
"process.env.NODE_ENV": JSON.stringify(
|
||||||
isProdBuild ? "production" : "development"
|
isProdBuild ? "production" : "development"
|
||||||
@@ -96,14 +83,6 @@ const createWebpackConfig = ({
|
|||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [".ts", ".js", ".json"],
|
extensions: [".ts", ".js", ".json"],
|
||||||
alias: {
|
|
||||||
react: "preact-compat",
|
|
||||||
"react-dom": "preact-compat",
|
|
||||||
// Not necessary unless you consume a module using `createClass`
|
|
||||||
"create-react-class": "preact-compat/lib/create-react-class",
|
|
||||||
// Not necessary unless you consume a module requiring `react-dom-factories`
|
|
||||||
"react-dom-factories": "preact-compat/lib/react-dom-factories",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: ({ chunk }) => {
|
filename: ({ chunk }) => {
|
||||||
@@ -136,7 +115,6 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
|||||||
core: "./src/entrypoints/core.ts",
|
core: "./src/entrypoints/core.ts",
|
||||||
compatibility: "./src/entrypoints/compatibility.ts",
|
compatibility: "./src/entrypoints/compatibility.ts",
|
||||||
"custom-panel": "./src/entrypoints/custom-panel.ts",
|
"custom-panel": "./src/entrypoints/custom-panel.ts",
|
||||||
"hass-icons": "./src/entrypoints/hass-icons.ts",
|
|
||||||
},
|
},
|
||||||
outputRoot: paths.root,
|
outputRoot: paths.root,
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
@@ -155,7 +133,7 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
|||||||
`/static/translations/${englishFilename}`
|
`/static/translations/${englishFilename}`
|
||||||
] = `build-translations/output/${englishFilename}`;
|
] = `build-translations/output/${englishFilename}`;
|
||||||
|
|
||||||
Object.keys(translationMetadata.fragments).forEach((fragment) => {
|
translationMetadata.fragments.forEach((fragment) => {
|
||||||
workBoxTranslationsTemplatedURLs[
|
workBoxTranslationsTemplatedURLs[
|
||||||
`/static/translations/${fragment}/${englishFilename}`
|
`/static/translations/${fragment}/${englishFilename}`
|
||||||
] = `build-translations/output/${fragment}/${englishFilename}`;
|
] = `build-translations/output/${fragment}/${englishFilename}`;
|
||||||
@@ -198,7 +176,7 @@ const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
|||||||
},
|
},
|
||||||
outputRoot: paths.demo_root,
|
outputRoot: paths.demo_root,
|
||||||
defineOverlay: {
|
defineOverlay: {
|
||||||
__VERSION__: JSON.stringify(`DEMO-${version}`),
|
__VERSION__: JSON.stringify(`DEMO-${env.version()}`),
|
||||||
__DEMO__: true,
|
__DEMO__: true,
|
||||||
},
|
},
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
@@ -221,6 +199,9 @@ const createCastConfig = ({ isProdBuild, latestBuild }) => {
|
|||||||
outputRoot: paths.cast_root,
|
outputRoot: paths.cast_root,
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
latestBuild,
|
latestBuild,
|
||||||
|
defineOverlay: {
|
||||||
|
__BACKWARDS_COMPAT__: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -245,9 +226,6 @@ const createHassioConfig = ({ isProdBuild, latestBuild }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
|
const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
|
||||||
if (!latestBuild) {
|
|
||||||
throw new Error("Gallery only supports latest build!");
|
|
||||||
}
|
|
||||||
const config = createWebpackConfig({
|
const config = createWebpackConfig({
|
||||||
entry: {
|
entry: {
|
||||||
entrypoint: path.resolve(paths.gallery_dir, "src/entrypoint.js"),
|
entrypoint: path.resolve(paths.gallery_dir, "src/entrypoint.js"),
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import "../../../src/resources/ha-style";
|
import "../../../src/resources/ha-style";
|
||||||
import "../../../src/resources/roboto";
|
import "../../../src/resources/roboto";
|
||||||
import "../../../src/components/ha-iconset-svg";
|
|
||||||
import "../../../src/resources/hass-icons";
|
|
||||||
import "./layout/hc-connect";
|
import "./layout/hc-connect";
|
||||||
|
@@ -1,51 +1,53 @@
|
|||||||
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
import { Auth, Connection } from "home-assistant-js-websocket";
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
html,
|
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { Connection, Auth } from "home-assistant-js-websocket";
|
|
||||||
import "@polymer/iron-icon";
|
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
|
||||||
import "@polymer/paper-item/paper-icon-item";
|
|
||||||
import "../../../../src/components/ha-icon";
|
|
||||||
import {
|
|
||||||
enableWrite,
|
|
||||||
askWrite,
|
|
||||||
saveTokens,
|
|
||||||
} from "../../../../src/common/auth/token_storage";
|
|
||||||
import {
|
|
||||||
ensureConnectedCastSession,
|
|
||||||
castSendShowLovelaceView,
|
|
||||||
} from "../../../../src/cast/receiver_messages";
|
|
||||||
import "../../../../src/layouts/loading-screen";
|
|
||||||
import { CastManager } from "../../../../src/cast/cast_manager";
|
import { CastManager } from "../../../../src/cast/cast_manager";
|
||||||
import {
|
import {
|
||||||
LovelaceConfig,
|
castSendShowLovelaceView,
|
||||||
getLovelaceCollection,
|
ensureConnectedCastSession,
|
||||||
getLegacyLovelaceCollection,
|
} from "../../../../src/cast/receiver_messages";
|
||||||
} from "../../../../src/data/lovelace";
|
import {
|
||||||
import "./hc-layout";
|
askWrite,
|
||||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
enableWrite,
|
||||||
import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute";
|
saveTokens,
|
||||||
|
} from "../../../../src/common/auth/token_storage";
|
||||||
import { atLeastVersion } from "../../../../src/common/config/version";
|
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||||
|
import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute";
|
||||||
|
import "../../../../src/components/ha-icon";
|
||||||
|
import {
|
||||||
|
getLegacyLovelaceCollection,
|
||||||
|
getLovelaceCollection,
|
||||||
|
LovelaceConfig,
|
||||||
|
} from "../../../../src/data/lovelace";
|
||||||
|
import "../../../../src/layouts/loading-screen";
|
||||||
|
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
||||||
|
import "./hc-layout";
|
||||||
|
import "@material/mwc-button/mwc-button";
|
||||||
|
|
||||||
@customElement("hc-cast")
|
@customElement("hc-cast")
|
||||||
class HcCast extends LitElement {
|
class HcCast extends LitElement {
|
||||||
@property() public auth!: Auth;
|
@property() public auth!: Auth;
|
||||||
|
|
||||||
@property() public connection!: Connection;
|
@property() public connection!: Connection;
|
||||||
|
|
||||||
@property() public castManager!: CastManager;
|
@property() public castManager!: CastManager;
|
||||||
|
|
||||||
@property() private askWrite = false;
|
@property() private askWrite = false;
|
||||||
|
|
||||||
@property() private lovelaceConfig?: LovelaceConfig | null;
|
@property() private lovelaceConfig?: LovelaceConfig | null;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this.lovelaceConfig === undefined) {
|
if (this.lovelaceConfig === undefined) {
|
||||||
return html`
|
return html` <loading-screen></loading-screen>> `;
|
||||||
<loading-screen></loading-screen>>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const error =
|
const error =
|
||||||
@@ -75,14 +77,12 @@ class HcCast extends LitElement {
|
|||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${error
|
${error
|
||||||
? html`
|
? html` <div class="card-content">${error}</div> `
|
||||||
<div class="card-content">${error}</div>
|
|
||||||
`
|
|
||||||
: !this.castManager.status
|
: !this.castManager.status
|
||||||
? html`
|
? html`
|
||||||
<p class="center-item">
|
<p class="center-item">
|
||||||
<mwc-button raised @click=${this._handleLaunch}>
|
<mwc-button raised @click=${this._handleLaunch}>
|
||||||
<iron-icon icon="hass:cast"></iron-icon>
|
<ha-icon icon="hass:cast"></ha-icon>
|
||||||
Start Casting
|
Start Casting
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
</p>
|
</p>
|
||||||
@@ -120,7 +120,7 @@ class HcCast extends LitElement {
|
|||||||
${this.castManager.status
|
${this.castManager.status
|
||||||
? html`
|
? html`
|
||||||
<mwc-button @click=${this._handleLaunch}>
|
<mwc-button @click=${this._handleLaunch}>
|
||||||
<iron-icon icon="hass:cast-connected"></iron-icon>
|
<ha-icon icon="hass:cast-connected"></ha-icon>
|
||||||
Manage
|
Manage
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
`
|
`
|
||||||
@@ -242,7 +242,7 @@ class HcCast extends LitElement {
|
|||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
mwc-button iron-icon {
|
mwc-button ha-icon {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
|
@@ -1,35 +1,35 @@
|
|||||||
import {
|
|
||||||
LitElement,
|
|
||||||
customElement,
|
|
||||||
property,
|
|
||||||
TemplateResult,
|
|
||||||
html,
|
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
|
||||||
import {
|
|
||||||
getAuth,
|
|
||||||
createConnection,
|
|
||||||
Auth,
|
|
||||||
getAuthOptions,
|
|
||||||
ERR_HASS_HOST_REQUIRED,
|
|
||||||
ERR_INVALID_HTTPS_TO_HTTP,
|
|
||||||
Connection,
|
|
||||||
ERR_CANNOT_CONNECT,
|
|
||||||
ERR_INVALID_AUTH,
|
|
||||||
} from "home-assistant-js-websocket";
|
|
||||||
import "@polymer/iron-icon";
|
|
||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import {
|
||||||
|
Auth,
|
||||||
|
Connection,
|
||||||
|
createConnection,
|
||||||
|
ERR_CANNOT_CONNECT,
|
||||||
|
ERR_HASS_HOST_REQUIRED,
|
||||||
|
ERR_INVALID_AUTH,
|
||||||
|
ERR_INVALID_HTTPS_TO_HTTP,
|
||||||
|
getAuth,
|
||||||
|
getAuthOptions,
|
||||||
|
} from "home-assistant-js-websocket";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
||||||
|
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
||||||
import {
|
import {
|
||||||
loadTokens,
|
loadTokens,
|
||||||
saveTokens,
|
saveTokens,
|
||||||
} from "../../../../src/common/auth/token_storage";
|
} from "../../../../src/common/auth/token_storage";
|
||||||
|
import "../../../../src/components/ha-icon";
|
||||||
import "../../../../src/layouts/loading-screen";
|
import "../../../../src/layouts/loading-screen";
|
||||||
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
|
||||||
import "./hc-layout";
|
|
||||||
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
|
||||||
import { registerServiceWorker } from "../../../../src/util/register-service-worker";
|
import { registerServiceWorker } from "../../../../src/util/register-service-worker";
|
||||||
|
import "./hc-layout";
|
||||||
|
|
||||||
const seeFAQ = (qid) => html`
|
const seeFAQ = (qid) => html`
|
||||||
See <a href="./faq.html${qid ? `#${qid}` : ""}">the FAQ</a> for more
|
See <a href="./faq.html${qid ? `#${qid}` : ""}">the FAQ</a> for more
|
||||||
@@ -61,13 +61,19 @@ const INTRO = html`
|
|||||||
@customElement("hc-connect")
|
@customElement("hc-connect")
|
||||||
export class HcConnect extends LitElement {
|
export class HcConnect extends LitElement {
|
||||||
@property() private loading = false;
|
@property() private loading = false;
|
||||||
|
|
||||||
// If we had stored credentials but we cannot connect,
|
// If we had stored credentials but we cannot connect,
|
||||||
// show a screen asking retry or logout.
|
// show a screen asking retry or logout.
|
||||||
@property() private cannotConnect = false;
|
@property() private cannotConnect = false;
|
||||||
|
|
||||||
@property() private error?: string | TemplateResult;
|
@property() private error?: string | TemplateResult;
|
||||||
|
|
||||||
@property() private auth?: Auth;
|
@property() private auth?: Auth;
|
||||||
|
|
||||||
@property() private connection?: Connection;
|
@property() private connection?: Connection;
|
||||||
|
|
||||||
@property() private castManager?: CastManager | null;
|
@property() private castManager?: CastManager | null;
|
||||||
|
|
||||||
private openDemo = false;
|
private openDemo = false;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -92,9 +98,7 @@ export class HcConnect extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.castManager === undefined || this.loading) {
|
if (this.castManager === undefined || this.loading) {
|
||||||
return html`
|
return html` <loading-screen></loading-screen> `;
|
||||||
<loading-screen></loading-screen>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.castManager === null) {
|
if (this.castManager === null) {
|
||||||
@@ -127,20 +131,16 @@ export class HcConnect extends LitElement {
|
|||||||
@keydown=${this._handleInputKeyDown}
|
@keydown=${this._handleInputKeyDown}
|
||||||
></paper-input>
|
></paper-input>
|
||||||
</p>
|
</p>
|
||||||
${this.error
|
${this.error ? html` <p class="error">${this.error}</p> ` : ""}
|
||||||
? html`
|
|
||||||
<p class="error">${this.error}</p>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<mwc-button @click=${this._handleDemo}>
|
<mwc-button @click=${this._handleDemo}>
|
||||||
Show Demo
|
Show Demo
|
||||||
<iron-icon
|
<ha-icon
|
||||||
.icon=${this.castManager.castState === "CONNECTED"
|
.icon=${this.castManager.castState === "CONNECTED"
|
||||||
? "hass:cast-connected"
|
? "hass:cast-connected"
|
||||||
: "hass:cast"}
|
: "hass:cast"}
|
||||||
></iron-icon>
|
></ha-icon>
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
<mwc-button @click=${this._handleConnect}>Authorize</mwc-button>
|
<mwc-button @click=${this._handleConnect}>Authorize</mwc-button>
|
||||||
@@ -211,7 +211,8 @@ export class HcConnect extends LitElement {
|
|||||||
if (value === "") {
|
if (value === "") {
|
||||||
this.error = "Please enter a Home Assistant URL.";
|
this.error = "Please enter a Home Assistant URL.";
|
||||||
return;
|
return;
|
||||||
} else if (value.indexOf("://") === -1) {
|
}
|
||||||
|
if (value.indexOf("://") === -1) {
|
||||||
this.error =
|
this.error =
|
||||||
"Please enter your full URL, including the protocol part (https://).";
|
"Please enter your full URL, including the protocol part (https://).";
|
||||||
return;
|
return;
|
||||||
@@ -315,7 +316,7 @@ export class HcConnect extends LitElement {
|
|||||||
color: darkred;
|
color: darkred;
|
||||||
}
|
}
|
||||||
|
|
||||||
mwc-button iron-icon {
|
mwc-button ha-icon {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,25 +1,28 @@
|
|||||||
import {
|
|
||||||
customElement,
|
|
||||||
LitElement,
|
|
||||||
TemplateResult,
|
|
||||||
html,
|
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
property,
|
|
||||||
} from "lit-element";
|
|
||||||
import {
|
import {
|
||||||
Auth,
|
Auth,
|
||||||
Connection,
|
Connection,
|
||||||
HassUser,
|
|
||||||
getUser,
|
getUser,
|
||||||
|
HassUser,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
|
|
||||||
@customElement("hc-layout")
|
@customElement("hc-layout")
|
||||||
class HcLayout extends LitElement {
|
class HcLayout extends LitElement {
|
||||||
@property() public subtitle?: string | undefined;
|
@property() public subtitle?: string | undefined;
|
||||||
|
|
||||||
@property() public auth?: Auth;
|
@property() public auth?: Auth;
|
||||||
|
|
||||||
@property() public connection?: Connection;
|
@property() public connection?: Connection;
|
||||||
|
|
||||||
@property() public user?: HassUser;
|
@property() public user?: HassUser;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -37,11 +40,7 @@ class HcLayout extends LitElement {
|
|||||||
this.auth.data.hassUrl.indexOf("//") + 2
|
this.auth.data.hassUrl.indexOf("//") + 2
|
||||||
)}</a
|
)}</a
|
||||||
>
|
>
|
||||||
${this.user
|
${this.user ? html` – ${this.user.name} ` : ""}
|
||||||
? html`
|
|
||||||
– ${this.user.name}
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
|
@@ -1 +1,2 @@
|
|||||||
|
/* eslint-disable no-undef */
|
||||||
export const castContext = cast.framework.CastReceiverContext.getInstance();
|
export const castContext = cast.framework.CastReceiverContext.getInstance();
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Entity, convertEntities } from "../../../../src/fake_data/entity";
|
import { convertEntities, Entity } from "../../../../src/fake_data/entity";
|
||||||
|
|
||||||
export const castDemoEntities: () => Entity[] = () =>
|
export const castDemoEntities: () => Entity[] = () =>
|
||||||
convertEntities({
|
convertEntities({
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
LovelaceConfig,
|
|
||||||
LovelaceCardConfig,
|
LovelaceCardConfig,
|
||||||
|
LovelaceConfig,
|
||||||
} from "../../../../src/data/lovelace";
|
} from "../../../../src/data/lovelace";
|
||||||
import { castContext } from "../cast_context";
|
import { castContext } from "../cast_context";
|
||||||
|
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
|
/* eslint-disable no-undef */
|
||||||
|
import { CAST_NS } from "../../../src/cast/const";
|
||||||
|
import { HassMessage } from "../../../src/cast/receiver_messages";
|
||||||
import "../../../src/resources/custom-card-support";
|
import "../../../src/resources/custom-card-support";
|
||||||
import { castContext } from "./cast_context";
|
import { castContext } from "./cast_context";
|
||||||
import { ReceivedMessage } from "./types";
|
|
||||||
import { HassMessage } from "../../../src/cast/receiver_messages";
|
|
||||||
import { HcMain } from "./layout/hc-main";
|
import { HcMain } from "./layout/hc-main";
|
||||||
import { CAST_NS } from "../../../src/cast/const";
|
import { ReceivedMessage } from "./types";
|
||||||
|
|
||||||
const controller = new HcMain();
|
const controller = new HcMain();
|
||||||
document.body.append(controller);
|
document.body.append(controller);
|
||||||
|
@@ -1,19 +1,20 @@
|
|||||||
import { HassElement } from "../../../../src/state/hass-element";
|
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||||
import "./hc-lovelace";
|
import { mockHistory } from "../../../../demo/src/stubs/history";
|
||||||
import { customElement, TemplateResult, html, property } from "lit-element";
|
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||||
import {
|
import {
|
||||||
MockHomeAssistant,
|
MockHomeAssistant,
|
||||||
provideHass,
|
provideHass,
|
||||||
} from "../../../../src/fake_data/provide_hass";
|
} from "../../../../src/fake_data/provide_hass";
|
||||||
|
import { HassElement } from "../../../../src/state/hass-element";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
|
||||||
import { castDemoEntities } from "../demo/cast-demo-entities";
|
import { castDemoEntities } from "../demo/cast-demo-entities";
|
||||||
import { castDemoLovelace } from "../demo/cast-demo-lovelace";
|
import { castDemoLovelace } from "../demo/cast-demo-lovelace";
|
||||||
import { mockHistory } from "../../../../demo/src/stubs/history";
|
import "./hc-lovelace";
|
||||||
|
|
||||||
@customElement("hc-demo")
|
@customElement("hc-demo")
|
||||||
class HcDemo extends HassElement {
|
class HcDemo extends HassElement {
|
||||||
@property() public lovelacePath!: string;
|
@property() public lovelacePath!: string;
|
||||||
|
|
||||||
@property() private _lovelaceConfig?: LovelaceConfig;
|
@property() private _lovelaceConfig?: LovelaceConfig;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -28,6 +29,7 @@ class HcDemo extends HassElement {
|
|||||||
></hc-lovelace>
|
></hc-lovelace>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this._initialize();
|
this._initialize();
|
||||||
|
@@ -1,17 +1,18 @@
|
|||||||
import {
|
import {
|
||||||
LitElement,
|
|
||||||
TemplateResult,
|
|
||||||
html,
|
|
||||||
customElement,
|
|
||||||
CSSResult,
|
|
||||||
css,
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
|
|
||||||
@customElement("hc-launch-screen")
|
@customElement("hc-launch-screen")
|
||||||
class HcLaunchScreen extends LitElement {
|
class HcLaunchScreen extends LitElement {
|
||||||
@property() public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property() public error?: string;
|
@property() public error?: string;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
@@ -22,11 +23,7 @@ class HcLaunchScreen extends LitElement {
|
|||||||
/>
|
/>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
${this.hass ? "Connected" : "Not Connected"}
|
${this.hass ? "Connected" : "Not Connected"}
|
||||||
${this.error
|
${this.error ? html` <p>Error: ${this.error}</p> ` : ""}
|
||||||
? html`
|
|
||||||
<p>Error: ${this.error}</p>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
import {
|
import {
|
||||||
LitElement,
|
|
||||||
TemplateResult,
|
|
||||||
html,
|
|
||||||
customElement,
|
|
||||||
CSSResult,
|
|
||||||
css,
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||||
import "../../../../src/panels/lovelace/views/hui-view";
|
|
||||||
import "../../../../src/panels/lovelace/views/hui-panel-view";
|
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
|
||||||
import { Lovelace } from "../../../../src/panels/lovelace/types";
|
import { Lovelace } from "../../../../src/panels/lovelace/types";
|
||||||
|
import "../../../../src/panels/lovelace/views/hui-panel-view";
|
||||||
|
import "../../../../src/panels/lovelace/views/hui-view";
|
||||||
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import "./hc-launch-screen";
|
import "./hc-launch-screen";
|
||||||
|
|
||||||
@customElement("hc-lovelace")
|
@customElement("hc-lovelace")
|
||||||
@@ -46,6 +46,7 @@ class HcLovelace extends LitElement {
|
|||||||
? html`
|
? html`
|
||||||
<hui-panel-view
|
<hui-panel-view
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
|
.lovelace=${lovelace}
|
||||||
.config=${this.lovelaceConfig.views[index]}
|
.config=${this.lovelaceConfig.views[index]}
|
||||||
></hui-panel-view>
|
></hui-panel-view>
|
||||||
`
|
`
|
||||||
|
@@ -1,31 +1,31 @@
|
|||||||
import {
|
import {
|
||||||
getAuth,
|
|
||||||
createConnection,
|
createConnection,
|
||||||
|
getAuth,
|
||||||
UnsubscribeFunc,
|
UnsubscribeFunc,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import { customElement, TemplateResult, html, property } from "lit-element";
|
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||||
import { HassElement } from "../../../../src/state/hass-element";
|
|
||||||
import {
|
|
||||||
HassMessage,
|
|
||||||
ConnectMessage,
|
|
||||||
ShowLovelaceViewMessage,
|
|
||||||
GetStatusMessage,
|
|
||||||
ShowDemoMessage,
|
|
||||||
} from "../../../../src/cast/receiver_messages";
|
|
||||||
import {
|
|
||||||
LovelaceConfig,
|
|
||||||
getLovelaceCollection,
|
|
||||||
fetchResources,
|
|
||||||
LegacyLovelaceConfig,
|
|
||||||
getLegacyLovelaceCollection,
|
|
||||||
} from "../../../../src/data/lovelace";
|
|
||||||
import "./hc-launch-screen";
|
|
||||||
import { castContext } from "../cast_context";
|
|
||||||
import { CAST_NS } from "../../../../src/cast/const";
|
import { CAST_NS } from "../../../../src/cast/const";
|
||||||
|
import {
|
||||||
|
ConnectMessage,
|
||||||
|
GetStatusMessage,
|
||||||
|
HassMessage,
|
||||||
|
ShowDemoMessage,
|
||||||
|
ShowLovelaceViewMessage,
|
||||||
|
} from "../../../../src/cast/receiver_messages";
|
||||||
import { ReceiverStatusMessage } from "../../../../src/cast/sender_messages";
|
import { ReceiverStatusMessage } from "../../../../src/cast/sender_messages";
|
||||||
import { loadLovelaceResources } from "../../../../src/panels/lovelace/common/load-resources";
|
|
||||||
import { isNavigationClick } from "../../../../src/common/dom/is-navigation-click";
|
|
||||||
import { atLeastVersion } from "../../../../src/common/config/version";
|
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||||
|
import { isNavigationClick } from "../../../../src/common/dom/is-navigation-click";
|
||||||
|
import {
|
||||||
|
fetchResources,
|
||||||
|
getLegacyLovelaceCollection,
|
||||||
|
getLovelaceCollection,
|
||||||
|
LegacyLovelaceConfig,
|
||||||
|
LovelaceConfig,
|
||||||
|
} from "../../../../src/data/lovelace";
|
||||||
|
import { loadLovelaceResources } from "../../../../src/panels/lovelace/common/load-resources";
|
||||||
|
import { HassElement } from "../../../../src/state/hass-element";
|
||||||
|
import { castContext } from "../cast_context";
|
||||||
|
import "./hc-launch-screen";
|
||||||
|
|
||||||
let resourcesLoaded = false;
|
let resourcesLoaded = false;
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ export class HcMain extends HassElement {
|
|||||||
@property() private _error?: string;
|
@property() private _error?: string;
|
||||||
|
|
||||||
private _unsubLovelace?: UnsubscribeFunc;
|
private _unsubLovelace?: UnsubscribeFunc;
|
||||||
|
|
||||||
private _urlPath?: string | null;
|
private _urlPath?: string | null;
|
||||||
|
|
||||||
public processIncomingMessage(msg: HassMessage) {
|
public processIncomingMessage(msg: HassMessage) {
|
||||||
@@ -52,16 +53,14 @@ export class HcMain extends HassElement {
|
|||||||
} else if (msg.type === "show_demo") {
|
} else if (msg.type === "show_demo") {
|
||||||
this._handleShowDemo(msg);
|
this._handleShowDemo(msg);
|
||||||
} else {
|
} else {
|
||||||
// tslint:disable-next-line: no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn("unknown msg type", msg);
|
console.warn("unknown msg type", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this._showDemo) {
|
if (this._showDemo) {
|
||||||
return html`
|
return html` <hc-demo .lovelacePath=${this._lovelacePath}></hc-demo> `;
|
||||||
<hc-demo .lovelacePath=${this._lovelacePath}></hc-demo>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -91,15 +90,17 @@ export class HcMain extends HassElement {
|
|||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
import("../second-load");
|
import("../second-load");
|
||||||
window.addEventListener("location-changed", () => {
|
window.addEventListener("location-changed", () => {
|
||||||
if (location.pathname.startsWith("/lovelace/")) {
|
const panelPath = `/${this._urlPath || "lovelace"}/`;
|
||||||
this._lovelacePath = location.pathname.substr(10);
|
if (location.pathname.startsWith(panelPath)) {
|
||||||
|
this._lovelacePath = location.pathname.substr(panelPath.length);
|
||||||
this._sendStatus();
|
this._sendStatus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.body.addEventListener("click", (ev) => {
|
document.body.addEventListener("click", (ev) => {
|
||||||
|
const panelPath = `/${this._urlPath || "lovelace"}/`;
|
||||||
const href = isNavigationClick(ev);
|
const href = isNavigationClick(ev);
|
||||||
if (href && href.startsWith("/lovelace/")) {
|
if (href && href.startsWith(panelPath)) {
|
||||||
this._lovelacePath = href.substr(10);
|
this._lovelacePath = href.substr(panelPath.length);
|
||||||
this._sendStatus();
|
this._sendStatus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -171,6 +172,9 @@ export class HcMain extends HassElement {
|
|||||||
this._error = "Cannot show Lovelace because we're not connected.";
|
this._error = "Cannot show Lovelace because we're not connected.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (msg.urlPath === "lovelace") {
|
||||||
|
msg.urlPath = null;
|
||||||
|
}
|
||||||
if (!this._unsubLovelace || this._urlPath !== msg.urlPath) {
|
if (!this._unsubLovelace || this._urlPath !== msg.urlPath) {
|
||||||
this._urlPath = msg.urlPath;
|
this._urlPath = msg.urlPath;
|
||||||
if (this._unsubLovelace) {
|
if (this._unsubLovelace) {
|
||||||
|
@@ -1,5 +1,3 @@
|
|||||||
import "web-animations-js/web-animations-next-lite.min";
|
import "web-animations-js/web-animations-next-lite.min";
|
||||||
import "../../../src/resources/hass-icons";
|
|
||||||
import "../../../src/resources/roboto";
|
import "../../../src/resources/roboto";
|
||||||
import "../../../src/components/ha-iconset-svg";
|
|
||||||
import "./layout/hc-lovelace";
|
import "./layout/hc-lovelace";
|
||||||
|
@@ -6,6 +6,6 @@ const { isProdBuild } = require("../build-scripts/env.js");
|
|||||||
const latestBuild = true;
|
const latestBuild = true;
|
||||||
|
|
||||||
module.exports = createCastConfig({
|
module.exports = createCastConfig({
|
||||||
isProdBuild,
|
isProdBuild: isProdBuild(),
|
||||||
latestBuild,
|
latestBuild,
|
||||||
});
|
});
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 805 B After Width: | Height: | Size: 803 B |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 160 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 781 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
demo/public/stub_config/bedroom.png
Normal file
After Width: | Height: | Size: 111 KiB |
BIN
demo/public/stub_config/floorplan.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
demo/public/stub_config/kitchen.png
Normal file
After Width: | Height: | Size: 115 KiB |
BIN
demo/public/stub_config/t-shirt-promo.png
Normal file
After Width: | Height: | Size: 185 KiB |
@@ -1,6 +1,6 @@
|
|||||||
import { DemoConfig } from "../types";
|
import { DemoConfig } from "../types";
|
||||||
import { demoLovelaceArsaboo } from "./lovelace";
|
|
||||||
import { demoEntitiesArsaboo } from "./entities";
|
import { demoEntitiesArsaboo } from "./entities";
|
||||||
|
import { demoLovelaceArsaboo } from "./lovelace";
|
||||||
import { demoThemeArsaboo } from "./theme";
|
import { demoThemeArsaboo } from "./theme";
|
||||||
|
|
||||||
export const demoArsaboo: DemoConfig = {
|
export const demoArsaboo: DemoConfig = {
|
||||||
|
@@ -21,7 +21,9 @@ export const demoConfigs: Array<() => Promise<DemoConfig>> = [
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
export let selectedDemoConfigIndex: number = 0;
|
// eslint-disable-next-line import/no-mutable-exports
|
||||||
|
export let selectedDemoConfigIndex = 0;
|
||||||
|
// eslint-disable-next-line import/no-mutable-exports
|
||||||
export let selectedDemoConfig: Promise<DemoConfig> = demoConfigs[
|
export let selectedDemoConfig: Promise<DemoConfig> = demoConfigs[
|
||||||
selectedDemoConfigIndex
|
selectedDemoConfigIndex
|
||||||
]();
|
]();
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { DemoConfig } from "../types";
|
import { DemoConfig } from "../types";
|
||||||
import { demoLovelaceJimpower } from "./lovelace";
|
|
||||||
import { demoEntitiesJimpower } from "./entities";
|
import { demoEntitiesJimpower } from "./entities";
|
||||||
|
import { demoLovelaceJimpower } from "./lovelace";
|
||||||
import { demoThemeJimpower } from "./theme";
|
import { demoThemeJimpower } from "./theme";
|
||||||
|
|
||||||
export const demoJimpower: DemoConfig = {
|
export const demoJimpower: DemoConfig = {
|
||||||
|
@@ -33,7 +33,7 @@ export const demoThemeJimpower = () => ({
|
|||||||
"label-badge-border-color": "green",
|
"label-badge-border-color": "green",
|
||||||
"paper-listbox-color": "var(--primary-color)",
|
"paper-listbox-color": "var(--primary-color)",
|
||||||
"paper-slider-disabled-secondary-color": "var(--disabled-text-color)",
|
"paper-slider-disabled-secondary-color": "var(--disabled-text-color)",
|
||||||
"paper-card-background-color": "#434954",
|
"card-background-color": "#434954",
|
||||||
"label-badge-text-color": "var(--primary-text-color)",
|
"label-badge-text-color": "var(--primary-text-color)",
|
||||||
"paper-slider-knob-start-color": "var(--accent-color)",
|
"paper-slider-knob-start-color": "var(--accent-color)",
|
||||||
"switch-unchecked-track-color": "var(--disabled-text-color)",
|
"switch-unchecked-track-color": "var(--disabled-text-color)",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { DemoConfig } from "../types";
|
import { DemoConfig } from "../types";
|
||||||
import { demoLovelaceKernehed } from "./lovelace";
|
|
||||||
import { demoEntitiesKernehed } from "./entities";
|
import { demoEntitiesKernehed } from "./entities";
|
||||||
|
import { demoLovelaceKernehed } from "./lovelace";
|
||||||
import { demoThemeKernehed } from "./theme";
|
import { demoThemeKernehed } from "./theme";
|
||||||
|
|
||||||
export const demoKernehed: DemoConfig = {
|
export const demoKernehed: DemoConfig = {
|
||||||
|
@@ -34,7 +34,7 @@ export const demoThemeKernehed = () => ({
|
|||||||
"label-badge-border-color": "green",
|
"label-badge-border-color": "green",
|
||||||
"paper-listbox-color": "#777777",
|
"paper-listbox-color": "#777777",
|
||||||
"paper-slider-disabled-secondary-color": "var(--disabled-text-color)",
|
"paper-slider-disabled-secondary-color": "var(--disabled-text-color)",
|
||||||
"paper-card-background-color": "#292929",
|
"card-background-color": "#292929",
|
||||||
"label-badge-text-color": "var(--primary-text-color)",
|
"label-badge-text-color": "var(--primary-text-color)",
|
||||||
"paper-slider-knob-start-color": "var(--accent-color)",
|
"paper-slider-knob-start-color": "var(--accent-color)",
|
||||||
"switch-unchecked-track-color": "var(--disabled-text-color)",
|
"switch-unchecked-track-color": "var(--disabled-text-color)",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { DemoConfig } from "../types";
|
import { DemoConfig } from "../types";
|
||||||
import { demoLovelaceTeachingbirds } from "./lovelace";
|
|
||||||
import { demoEntitiesTeachingbirds } from "./entities";
|
import { demoEntitiesTeachingbirds } from "./entities";
|
||||||
|
import { demoLovelaceTeachingbirds } from "./lovelace";
|
||||||
import { demoThemeTeachingbirds } from "./theme";
|
import { demoThemeTeachingbirds } from "./theme";
|
||||||
|
|
||||||
export const demoTeachingbirds: DemoConfig = {
|
export const demoTeachingbirds: DemoConfig = {
|
||||||
|
@@ -63,8 +63,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
elements: [
|
elements: [
|
||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
"--iron-icon-width": "100px",
|
"--mdc-icon-size": "100px",
|
||||||
"--iron-icon-height": "100px",
|
|
||||||
top: "50%",
|
top: "50%",
|
||||||
left: "50%",
|
left: "50%",
|
||||||
},
|
},
|
||||||
|