Compare commits
451 Commits
mdi-icons
...
template-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72bf0c918a | ||
|
|
419f5d13bf | ||
|
|
16549b3404 | ||
|
|
cbddebeaa8 | ||
|
|
bbe4c95109 | ||
|
|
4c6f9f0dd8 | ||
|
|
90f7dba793 | ||
|
|
7c492338a2 | ||
|
|
530f494df8 | ||
|
|
8fd1f35c59 | ||
|
|
af1518e924 | ||
|
|
473e381d75 | ||
|
|
7d3acc747d | ||
|
|
bf7424a67c | ||
|
|
a856337eae | ||
|
|
6cf47ba4eb | ||
|
|
3b7a189708 | ||
|
|
79c542b76a | ||
|
|
e37b7bd73f | ||
|
|
d6f3c34b33 | ||
|
|
bc5cb46e7d | ||
|
|
c7b747c4fa | ||
|
|
d3c51d7acd | ||
|
|
b6881d797c | ||
|
|
b9f802939c | ||
|
|
6558c2c065 | ||
|
|
37a089c868 | ||
|
|
f68eff6bb3 | ||
|
|
88a525f1a7 | ||
|
|
34fddd5940 | ||
|
|
0e5d6fe8d8 | ||
|
|
e1342a0d9d | ||
|
|
0cc2d3aaa7 | ||
|
|
67814505b3 | ||
|
|
bae29c6d62 | ||
|
|
a0e67d4c03 | ||
|
|
131bc5fbf7 | ||
|
|
051218e29b | ||
|
|
6ace8307d8 | ||
|
|
e84bef44b7 | ||
|
|
3186d762f2 | ||
|
|
c97a3b0a56 | ||
|
|
78f1bb3b91 | ||
|
|
67707fbc90 | ||
|
|
2a57ffa615 | ||
|
|
216fce74f8 | ||
|
|
6cd3e6652a | ||
|
|
fe7d79cee6 | ||
|
|
2f4e7b388b | ||
|
|
2e289cd152 | ||
|
|
21a3dcf06c | ||
|
|
7f56add914 | ||
|
|
88701c6167 | ||
|
|
e4ce6117a1 | ||
|
|
cec2a61bdf | ||
|
|
8275ac5853 | ||
|
|
b7bcf97365 | ||
|
|
fa28b480f1 | ||
|
|
4bb95b7396 | ||
|
|
5a9bd73e8b | ||
|
|
4fe0276914 | ||
|
|
5e8bda55b4 | ||
|
|
d09c4898c1 | ||
|
|
6ae67ed299 | ||
|
|
32ff166a74 | ||
|
|
8feae04281 | ||
|
|
129f9c147b | ||
|
|
6e336dd207 | ||
|
|
161561c48a | ||
|
|
c162e84383 | ||
|
|
dc8d80a6e5 | ||
|
|
293f67968c | ||
|
|
4dcf26236e | ||
|
|
a0e8d69243 | ||
|
|
33cd9bf516 | ||
|
|
0132797f2f | ||
|
|
7e2db0aa4e | ||
|
|
cc1d50491b | ||
|
|
461b86a04b | ||
|
|
9a3a7c28f4 | ||
|
|
1c9d0200ca | ||
|
|
0037cd2e69 | ||
|
|
028ae061da | ||
|
|
2e47763ecc | ||
|
|
924e4a45d0 | ||
|
|
8361b9553b | ||
|
|
e52be20fba | ||
|
|
da12233ade | ||
|
|
57500f6c97 | ||
|
|
199e17d0b1 | ||
|
|
3b91343082 | ||
|
|
1753c9163c | ||
|
|
89e5953e89 | ||
|
|
5bfd25c8c6 | ||
|
|
e555b24f50 | ||
|
|
14db37459f | ||
|
|
1d9779d47c | ||
|
|
3dedbc5457 | ||
|
|
facb3266c6 | ||
|
|
01fe5dd2f7 | ||
|
|
9b22b1e499 | ||
|
|
4bc8818145 | ||
|
|
48ef8c86c2 | ||
|
|
89f359a52f | ||
|
|
13b8160d74 | ||
|
|
f1c16d6674 | ||
|
|
76a088e177 | ||
|
|
630d8c3bb6 | ||
|
|
744efa30f2 | ||
|
|
bf4a94dc48 | ||
|
|
ce4ba2f6f1 | ||
|
|
5b232b5d35 | ||
|
|
35151bbac7 | ||
|
|
f0e959319e | ||
|
|
d0c4475724 | ||
|
|
99935f1e59 | ||
|
|
fbb43821ba | ||
|
|
c7f5c6c1d1 | ||
|
|
d26f1fa371 | ||
|
|
c3718ff7dd | ||
|
|
d63493a859 | ||
|
|
a72183851a | ||
|
|
40b2387667 | ||
|
|
d814aa36a7 | ||
|
|
e37eebe4ad | ||
|
|
0baaaefdf8 | ||
|
|
58a58906e7 | ||
|
|
bec0d9b00e | ||
|
|
e6a4ab789b | ||
|
|
36c1d3230c | ||
|
|
30466ec3fe | ||
|
|
ce414a5ca9 | ||
|
|
e4e6edd573 | ||
|
|
79927f4dc9 | ||
|
|
603b833757 | ||
|
|
ba99d1a10d | ||
|
|
efe97e8f51 | ||
|
|
5ec23bb7ab | ||
|
|
9b4d01ab75 | ||
|
|
40191a88d4 | ||
|
|
a19477d179 | ||
|
|
bf98a78f3d | ||
|
|
ba4c2fc1bd | ||
|
|
b56e9ef028 | ||
|
|
dbbd34c520 | ||
|
|
ccb69dbdfa | ||
|
|
11e555ef6f | ||
|
|
61e17395c9 | ||
|
|
733ce3b6b8 | ||
|
|
375f143199 | ||
|
|
2419f35eb9 | ||
|
|
21867c3576 | ||
|
|
28853b28bc | ||
|
|
e2f27568a5 | ||
|
|
98b2b796b0 | ||
|
|
b8f3fcf00b | ||
|
|
d3fda9a821 | ||
|
|
19e69dc13e | ||
|
|
48543a2dad | ||
|
|
b22f5ae5c2 | ||
|
|
2acb6a28fe | ||
|
|
1064cdb79d | ||
|
|
bd7cb1c877 | ||
|
|
6c314982dc | ||
|
|
d54710f113 | ||
|
|
1346156ecd | ||
|
|
a2d9f9b417 | ||
|
|
3de78cca2d | ||
|
|
5fa7cd9fa9 | ||
|
|
a78c00fb41 | ||
|
|
edc2a03d1c | ||
|
|
174f8f5823 | ||
|
|
9fbc94e8d8 | ||
|
|
6aff35196d | ||
|
|
eceed4ed74 | ||
|
|
7428731eac | ||
|
|
89b07ea0ae | ||
|
|
d16daf0fd9 | ||
|
|
211ab4eea8 | ||
|
|
dbd53f8d14 | ||
|
|
a27680b8c0 | ||
|
|
07fc9b98cc | ||
|
|
33582c0448 | ||
|
|
73be0fef75 | ||
|
|
611202c905 | ||
|
|
e553f35a68 | ||
|
|
673649a603 | ||
|
|
c4ed743370 | ||
|
|
682fa0d3eb | ||
|
|
30f34eee22 | ||
|
|
eab76bf85b | ||
|
|
bcf405bf9d | ||
|
|
3c4b0d4a74 | ||
|
|
fb9bd0eb7d | ||
|
|
7e2dc04123 | ||
|
|
54ec37994c | ||
|
|
4a5935ee36 | ||
|
|
01b9a07320 | ||
|
|
0fcf0dcd18 | ||
|
|
80481f142a | ||
|
|
2be08ce7ab | ||
|
|
37eb5af3d4 | ||
|
|
8c8151be92 | ||
|
|
baf31d1c1e | ||
|
|
af2250835a | ||
|
|
6f2a759ba3 | ||
|
|
5065901196 | ||
|
|
41b59e6e11 | ||
|
|
43afdaadc6 | ||
|
|
83c5151792 | ||
|
|
0880ab67c6 | ||
|
|
c0b2143c7c | ||
|
|
c1de162c99 | ||
|
|
a7ef8aba68 | ||
|
|
3ee4c11a99 | ||
|
|
990ae10dc2 | ||
|
|
52b2fd046b | ||
|
|
9f41f80a91 | ||
|
|
eec4a91ad8 | ||
|
|
7c51001c3c | ||
|
|
a4ea4b1f5f | ||
|
|
19fc37539e | ||
|
|
ce7acb0feb | ||
|
|
105b7678b8 | ||
|
|
b67575586e | ||
|
|
3dc6898673 | ||
|
|
a73754c1b5 | ||
|
|
1ebf1c00d6 | ||
|
|
7dac7d757e | ||
|
|
b1f3192b95 | ||
|
|
16984d18bb | ||
|
|
e603893d77 | ||
|
|
a7998b30c6 | ||
|
|
3277a4e8c3 | ||
|
|
7e769d0e14 | ||
|
|
713e0579f8 | ||
|
|
6e130cc020 | ||
|
|
eb036a12d9 | ||
|
|
534d1f5055 | ||
|
|
cbef909657 | ||
|
|
874f3b32b3 | ||
|
|
2fd017cf73 | ||
|
|
5740b018a7 | ||
|
|
288bf6805a | ||
|
|
02d37a369a | ||
|
|
1d316c3258 | ||
|
|
a56ce62f1a | ||
|
|
c268f42851 | ||
|
|
7251e802ab | ||
|
|
5b1a2d10c2 | ||
|
|
2dd7f292b1 | ||
|
|
213c53e307 | ||
|
|
ce07dfd8ac | ||
|
|
c1dba462e8 | ||
|
|
47f0d74812 | ||
|
|
ce80285f8d | ||
|
|
d2dd1a43dd | ||
|
|
12d73fe90d | ||
|
|
c2741638b2 | ||
|
|
4a7fb3d509 | ||
|
|
f6ff652ca4 | ||
|
|
6165cb0f83 | ||
|
|
1f361b7b10 | ||
|
|
5269ff978b | ||
|
|
55595493a9 | ||
|
|
ad3ff0aba7 | ||
|
|
ce48546cef | ||
|
|
35b3bc995e | ||
|
|
63f60019d1 | ||
|
|
0d741b6275 | ||
|
|
0df9080bbb | ||
|
|
ddcf89e6a2 | ||
|
|
5de225d5d4 | ||
|
|
5cddb482f1 | ||
|
|
c000d724de | ||
|
|
504055f331 | ||
|
|
7f6880f40e | ||
|
|
02e4e3c892 | ||
|
|
993d73c359 | ||
|
|
97ca0b818e | ||
|
|
44166f76d4 | ||
|
|
557d6d37a1 | ||
|
|
d3ad56a307 | ||
|
|
0641022ec5 | ||
|
|
80c7a8473a | ||
|
|
d9a954ca91 | ||
|
|
c219f64322 | ||
|
|
f7a9ecff21 | ||
|
|
2b3126ae04 | ||
|
|
934c227545 | ||
|
|
cc0515c217 | ||
|
|
55ba75f2bc | ||
|
|
c220228566 | ||
|
|
26b476ab3c | ||
|
|
b8a67d530f | ||
|
|
b08c96d2db | ||
|
|
4773c39a57 | ||
|
|
892843b290 | ||
|
|
733244531e | ||
|
|
66633273e2 | ||
|
|
0405adcd16 | ||
|
|
426a7ac8dd | ||
|
|
3bf6205ff7 | ||
|
|
c7f4986e61 | ||
|
|
0f0a3fdaf7 | ||
|
|
7d6911b140 | ||
|
|
b8777539d7 | ||
|
|
b5b1849ab3 | ||
|
|
0e10c81025 | ||
|
|
5fc0eaef1a | ||
|
|
113718c3c1 | ||
|
|
701bea6cae | ||
|
|
8d516ed12a | ||
|
|
667c5744f2 | ||
|
|
80b7c840e2 | ||
|
|
919c86796f | ||
|
|
c90c88ecbf | ||
|
|
d9ba0e2c46 | ||
|
|
45b2fc590b | ||
|
|
17ffdb0247 | ||
|
|
c2fba15fc6 | ||
|
|
5937be695f | ||
|
|
a076fcde84 | ||
|
|
ede9931903 | ||
|
|
722e01608c | ||
|
|
af926370d6 | ||
|
|
5971aee02e | ||
|
|
cce7ad449a | ||
|
|
d437dd5919 | ||
|
|
f1980730d2 | ||
|
|
47773e9cae | ||
|
|
60969b0916 | ||
|
|
ecc7925d03 | ||
|
|
6d3010dcc7 | ||
|
|
0164bafbf1 | ||
|
|
3940606167 | ||
|
|
da9faccada | ||
|
|
7e708b3bf7 | ||
|
|
05630c9896 | ||
|
|
369c56db73 | ||
|
|
9873459169 | ||
|
|
7776b3766b | ||
|
|
29c9004654 | ||
|
|
601c909004 | ||
|
|
72aa9a3b62 | ||
|
|
2ecf7bca97 | ||
|
|
cbdfaccdb2 | ||
|
|
93d1b9a2d5 | ||
|
|
bfb5ee794e | ||
|
|
9ae8bd238b | ||
|
|
98a64e3114 | ||
|
|
0171f3aec7 | ||
|
|
2c827bab9a | ||
|
|
ec920093d4 | ||
|
|
4289ff6652 | ||
|
|
cd32ef60da | ||
|
|
6ef3d091e1 | ||
|
|
0f59496778 | ||
|
|
795b670b3c | ||
|
|
4ad65e3d69 | ||
|
|
f48b1150cf | ||
|
|
198db8bc68 | ||
|
|
3ae447ca44 | ||
|
|
a2ec878ef0 | ||
|
|
d43b5d3337 | ||
|
|
11e3503dc2 | ||
|
|
accf44b769 | ||
|
|
b612c0e0d6 | ||
|
|
771c7518e6 | ||
|
|
4f2bad034a | ||
|
|
0456669aeb | ||
|
|
2eb71321e7 | ||
|
|
d2e9e22e4e | ||
|
|
e2427c8dce | ||
|
|
26162815c8 | ||
|
|
d0c86ea2f7 | ||
|
|
4f5b4d4472 | ||
|
|
10d71587e7 | ||
|
|
9ac777d687 | ||
|
|
7d1f9f3981 | ||
|
|
a214ab463e | ||
|
|
2f21f6ef8a | ||
|
|
590cd8500d | ||
|
|
f48a28264f | ||
|
|
51953bce09 | ||
|
|
c445d4b839 | ||
|
|
9dabce1dd7 | ||
|
|
6b77f08d86 | ||
|
|
50e03d41ab | ||
|
|
4759c89628 | ||
|
|
458ab9b1e0 | ||
|
|
dfb2a7153b | ||
|
|
e9141d82f3 | ||
|
|
d9f42712e4 | ||
|
|
da0658f3d9 | ||
|
|
412a5a6d8e | ||
|
|
9cf9e6edd8 | ||
|
|
28050fc9fb | ||
|
|
ea9f227fa8 | ||
|
|
05164e90fb | ||
|
|
97156ccf8a | ||
|
|
003d55968e | ||
|
|
98dd21b75c | ||
|
|
a349e34bc2 | ||
|
|
245c825cbf | ||
|
|
4ba6698c4b | ||
|
|
dac6edea90 | ||
|
|
b2e2dbe0c2 | ||
|
|
f822fa0d57 | ||
|
|
bbee94edba | ||
|
|
c39c408332 | ||
|
|
dde4a40e69 | ||
|
|
1afa4d2868 | ||
|
|
d25f371d6c | ||
|
|
948261d1d1 | ||
|
|
04b7749f85 | ||
|
|
8668f0ff5b | ||
|
|
b7d8ff6c99 | ||
|
|
0894a30f13 | ||
|
|
bd511887a7 | ||
|
|
0304c0eca0 | ||
|
|
6d5c6e2fbc | ||
|
|
e7e7912519 | ||
|
|
b9c41d8f99 | ||
|
|
25a2264ac3 | ||
|
|
ad64657c74 | ||
|
|
106f18a73a | ||
|
|
0fb38140a6 | ||
|
|
60133941ae | ||
|
|
76db64c073 | ||
|
|
24b390ba03 | ||
|
|
b4d34d9085 | ||
|
|
f80bea27a9 | ||
|
|
4b846964be | ||
|
|
e6357e2eef | ||
|
|
d538b6145f | ||
|
|
229ba3a75c | ||
|
|
672b867847 | ||
|
|
26abb4301d | ||
|
|
ed2c4e2642 | ||
|
|
00dbba04a2 | ||
|
|
4f4edb109f | ||
|
|
7d5a27ec0f | ||
|
|
667c828359 | ||
|
|
085c6f8bdd | ||
|
|
5cca5bfe86 | ||
|
|
4999f1ad51 | ||
|
|
61dbae8b8b | ||
|
|
ba3cc7df0f | ||
|
|
090ad34f78 | ||
|
|
b2460cbc3d |
13
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.148.1/containers/python-3/.devcontainer/base.Dockerfile
|
||||||
|
FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.9
|
||||||
|
|
||||||
|
ENV \
|
||||||
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
|
DEVCONTAINER=true \
|
||||||
|
PATH=$PATH:./node_modules/.bin
|
||||||
|
|
||||||
|
# Install nvm
|
||||||
|
COPY .nvmrc /tmp/.nvmrc
|
||||||
|
RUN \
|
||||||
|
su vscode -c \
|
||||||
|
"source /usr/local/share/nvm/nvm.sh && nvm install $(cat /tmp/.nvmrc) 2>&1"
|
||||||
31
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "Home Assistant Frontend",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".."
|
||||||
|
},
|
||||||
|
"appPort": 8123,
|
||||||
|
"context": "..",
|
||||||
|
"postCreateCommand": "script/bootstrap",
|
||||||
|
"extensions": [
|
||||||
|
"github.vscode-pull-request-github",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"ms-vscode.vscode-typescript-tslint-plugin",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"bierner.lit-html",
|
||||||
|
"runem.lit-plugin",
|
||||||
|
"ms-python.vscode-pylance"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.shell.linux": "/bin/bash",
|
||||||
|
"files.eol": "\n",
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.formatOnPaste": false,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnType": true,
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -75,13 +75,16 @@
|
|||||||
"object-curly-newline": 0,
|
"object-curly-newline": 0,
|
||||||
"default-case": 0,
|
"default-case": 0,
|
||||||
"wc/no-self-class": 0,
|
"wc/no-self-class": 0,
|
||||||
|
"no-shadow": 0,
|
||||||
"@typescript-eslint/camelcase": 0,
|
"@typescript-eslint/camelcase": 0,
|
||||||
"@typescript-eslint/ban-ts-ignore": 0,
|
"@typescript-eslint/ban-ts-comment": 0,
|
||||||
"@typescript-eslint/no-use-before-define": 0,
|
"@typescript-eslint/no-use-before-define": 0,
|
||||||
"@typescript-eslint/no-non-null-assertion": 0,
|
"@typescript-eslint/no-non-null-assertion": 0,
|
||||||
"@typescript-eslint/no-explicit-any": 0,
|
"@typescript-eslint/no-explicit-any": 0,
|
||||||
"@typescript-eslint/no-unused-vars": 0,
|
"@typescript-eslint/no-unused-vars": 0,
|
||||||
"@typescript-eslint/explicit-function-return-type": 0
|
"@typescript-eslint/explicit-function-return-type": 0,
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||||
|
"@typescript-eslint/no-shadow": ["error"]
|
||||||
},
|
},
|
||||||
"plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"],
|
"plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"],
|
||||||
"processor": "disable/disable"
|
"processor": "disable/disable"
|
||||||
|
|||||||
26
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
@@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
name: Request a feature for the UI, Frontend or Lovelace
|
|
||||||
about: Request an new feature for the Home Assistant frontend.
|
|
||||||
labels: feature request
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
DO NOT DELETE ANY TEXT from this template!
|
|
||||||
Otherwise, your request may be closed without comment.
|
|
||||||
-->
|
|
||||||
|
|
||||||
## The request
|
|
||||||
|
|
||||||
<!--
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
|
|
||||||
## The alternatives
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Are you currently using, or have you considered alternatives?
|
|
||||||
If so, could you please describe those?
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Additional information
|
|
||||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,8 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
|
- name: Request a feature for the UI, Frontend or Lovelace
|
||||||
|
url: https://github.com/home-assistant/frontend/discussions/category_choices
|
||||||
|
about: Request an new feature for the Home Assistant frontend.
|
||||||
- name: Report a bug that is NOT related to the UI, Frontend or Lovelace
|
- name: Report a bug that is NOT related to the UI, Frontend or Lovelace
|
||||||
url: https://github.com/home-assistant/core/issues
|
url: https://github.com/home-assistant/core/issues
|
||||||
about: This is the issue tracker for our frontend. Please report other issues with the backend repository.
|
about: This is the issue tracker for our frontend. Please report other issues with the backend repository.
|
||||||
|
|||||||
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -18,8 +18,8 @@
|
|||||||
<!--
|
<!--
|
||||||
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 or discussion
|
||||||
additional information section.
|
in the additional information section.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Type of change
|
## Type of change
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- 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 or discussion:
|
||||||
- Link to documentation pull request:
|
- Link to documentation pull request:
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|||||||
27
.github/lock.yml
vendored
@@ -1,27 +0,0 @@
|
|||||||
# Configuration for Lock Threads - https://github.com/dessant/lock-threads
|
|
||||||
|
|
||||||
# Number of days of inactivity before a closed issue or pull request is locked
|
|
||||||
daysUntilLock: 1
|
|
||||||
|
|
||||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
|
||||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
|
||||||
skipCreatedBefore: 2020-01-01
|
|
||||||
|
|
||||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
|
||||||
exemptLabels: []
|
|
||||||
|
|
||||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
|
||||||
lockLabel: false
|
|
||||||
|
|
||||||
# Comment to post before locking. Set to `false` to disable
|
|
||||||
lockComment: false
|
|
||||||
|
|
||||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
|
||||||
setLockReason: false
|
|
||||||
|
|
||||||
# Limit to only `issues` or `pulls`
|
|
||||||
only: pulls
|
|
||||||
|
|
||||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
|
||||||
issues:
|
|
||||||
daysUntilLock: 30
|
|
||||||
56
.github/stale.yml
vendored
@@ -1,56 +0,0 @@
|
|||||||
# Configuration for probot-stale - https://github.com/probot/stale
|
|
||||||
|
|
||||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
|
||||||
daysUntilStale: 90
|
|
||||||
|
|
||||||
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
|
|
||||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
|
||||||
daysUntilClose: 7
|
|
||||||
|
|
||||||
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
|
||||||
onlyLabels: []
|
|
||||||
|
|
||||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
|
||||||
exemptLabels:
|
|
||||||
- feature request
|
|
||||||
- Help wanted
|
|
||||||
- to do
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a project (defaults to false)
|
|
||||||
exemptProjects: true
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a milestone (defaults to false)
|
|
||||||
exemptMilestones: true
|
|
||||||
|
|
||||||
# Set to true to ignore issues with an assignee (defaults to false)
|
|
||||||
exemptAssignees: false
|
|
||||||
|
|
||||||
# Label to use when marking as stale
|
|
||||||
staleLabel: stale
|
|
||||||
|
|
||||||
# Comment to post when marking as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
There hasn't been any activity on this issue recently. Due to the high number
|
|
||||||
of incoming GitHub notifications, we have to clean some of the old issues,
|
|
||||||
as many of them have already been resolved with the latest updates.
|
|
||||||
|
|
||||||
Please make sure to update to the latest Home Assistant version and check
|
|
||||||
if that solves the issue. Let us know if that works for you by adding a
|
|
||||||
comment 👍
|
|
||||||
|
|
||||||
This issue now has been marked as stale and will be closed if no further
|
|
||||||
activity occurs. Thank you for your contributions.
|
|
||||||
|
|
||||||
# Comment to post when removing the stale label.
|
|
||||||
# unmarkComment: >
|
|
||||||
# Your comment here.
|
|
||||||
|
|
||||||
# Comment to post when closing a stale Issue or Pull Request.
|
|
||||||
# closeComment: >
|
|
||||||
# Your comment here.
|
|
||||||
|
|
||||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
|
||||||
limitPerRun: 30
|
|
||||||
|
|
||||||
# Limit to only `issues` or `pulls`
|
|
||||||
only: issues
|
|
||||||
20
.github/workflows/lock.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Lock
|
||||||
|
|
||||||
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 * * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lock:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: dessant/lock-threads@v2.0.1
|
||||||
|
with:
|
||||||
|
github-token: ${{ github.token }}
|
||||||
|
issue-lock-inactive-days: "30"
|
||||||
|
issue-exclude-created-before: "2020-10-01T00:00:00Z"
|
||||||
|
issue-lock-reason: ""
|
||||||
|
pr-lock-inactive-days: "1"
|
||||||
|
pr-exclude-created-before: "2020-11-01T00:00:00Z"
|
||||||
|
pr-lock-reason: ""
|
||||||
42
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: Stale
|
||||||
|
|
||||||
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 * * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 90 days stale policy
|
||||||
|
uses: actions/stale@v3.0.13
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
days-before-stale: 90
|
||||||
|
days-before-close: 7
|
||||||
|
operations-per-run: 25
|
||||||
|
remove-stale-when-updated: true
|
||||||
|
stale-issue-label: "stale"
|
||||||
|
exempt-issue-labels: "no-stale,Help%20wanted,help-wanted,feature-request,feature%20request"
|
||||||
|
stale-issue-message: >
|
||||||
|
There hasn't been any activity on this issue recently. Due to the
|
||||||
|
high number of incoming GitHub notifications, we have to clean some
|
||||||
|
of the old issues, as many of them have already been resolved with
|
||||||
|
the latest updates.
|
||||||
|
|
||||||
|
Please make sure to update to the latest Home Assistant version and
|
||||||
|
check if that solves the issue. Let us know if that works for you by
|
||||||
|
adding a comment 👍
|
||||||
|
|
||||||
|
This issue has now been marked as stale and will be closed if no
|
||||||
|
further activity occurs. Thank you for your contributions.
|
||||||
|
|
||||||
|
stale-pr-label: "stale"
|
||||||
|
exempt-pr-labels: "no-stale"
|
||||||
|
stale-pr-message: >
|
||||||
|
There hasn't been any activity on this pull request recently. This
|
||||||
|
pull request has been automatically marked as stale because of that
|
||||||
|
and will be closed if no further activity occurs within 7 days.
|
||||||
|
|
||||||
|
Thank you for your contributions.
|
||||||
5
.gitignore
vendored
@@ -23,6 +23,8 @@ dist
|
|||||||
# vscode
|
# vscode
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
|
||||||
# Cast dev settings
|
# Cast dev settings
|
||||||
src/cast/dev_const.ts
|
src/cast/dev_const.ts
|
||||||
@@ -33,3 +35,6 @@ yarn-error.log
|
|||||||
|
|
||||||
#asdf
|
#asdf
|
||||||
.tool-versions
|
.tool-versions
|
||||||
|
|
||||||
|
# Home Assistant config
|
||||||
|
/config
|
||||||
|
|||||||
44
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
// https://github.com/microsoft/vscode-js-debug/blob/master/OPTIONS.md
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug Frontend",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "pwa-chrome",
|
||||||
|
"url": "http://localhost:8123/",
|
||||||
|
"webRoot": "${workspaceFolder}/hass_frontend",
|
||||||
|
"disableNetworkCache": true,
|
||||||
|
"preLaunchTask": "Develop Frontend",
|
||||||
|
"outFiles": [
|
||||||
|
"${workspaceFolder}/hass_frontend/frontend_latest/*.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug Gallery",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "pwa-chrome",
|
||||||
|
"url": "http://localhost:8100/",
|
||||||
|
"webRoot": "${workspaceFolder}/gallery/dist",
|
||||||
|
"disableNetworkCache": true,
|
||||||
|
"preLaunchTask": "Develop Gallery"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug Demo",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "pwa-chrome",
|
||||||
|
"url": "http://localhost:8090/",
|
||||||
|
"webRoot": "${workspaceFolder}/demo/dist",
|
||||||
|
"disableNetworkCache": true,
|
||||||
|
"preLaunchTask": "Develop Demo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Debug Cast",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "pwa-chrome",
|
||||||
|
"url": "http://localhost:8080/",
|
||||||
|
"webRoot": "${workspaceFolder}/cast/dist",
|
||||||
|
"disableNetworkCache": true,
|
||||||
|
"preLaunchTask": "Develop Cast"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
208
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Develop Frontend",
|
||||||
|
"type": "gulp",
|
||||||
|
"task": "develop-app",
|
||||||
|
// Sync changes here to other tasks until issue resolved
|
||||||
|
// https://github.com/Microsoft/vscode/issues/61497
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "ha-build",
|
||||||
|
"source": "ha-build",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"severity": "error",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||||
|
"severity": 1,
|
||||||
|
"file": 2,
|
||||||
|
"message": 3,
|
||||||
|
"line": 4,
|
||||||
|
"column": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "Changes detected. Starting compilation",
|
||||||
|
"endsPattern": "Build done @"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isBackground": true,
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Develop Supervisor panel",
|
||||||
|
"type": "gulp",
|
||||||
|
"task": "develop-hassio",
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "ha-build",
|
||||||
|
"source": "ha-build",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"severity": "error",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||||
|
"severity": 1,
|
||||||
|
"file": 2,
|
||||||
|
"message": 3,
|
||||||
|
"line": 4,
|
||||||
|
"column": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "Changes detected. Starting compilation",
|
||||||
|
"endsPattern": "Build done @"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"isBackground": true,
|
||||||
|
"group": "build",
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Develop Gallery",
|
||||||
|
"type": "gulp",
|
||||||
|
"task": "develop-gallery",
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "ha-build",
|
||||||
|
"source": "ha-build",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"severity": "error",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||||
|
"severity": 1,
|
||||||
|
"file": 2,
|
||||||
|
"message": 3,
|
||||||
|
"line": 4,
|
||||||
|
"column": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "Changes detected. Starting compilation",
|
||||||
|
"endsPattern": "Build done @"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"isBackground": true,
|
||||||
|
"group": "build",
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Develop Demo",
|
||||||
|
"type": "gulp",
|
||||||
|
"task": "develop-demo",
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "ha-build",
|
||||||
|
"source": "ha-build",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"severity": "error",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||||
|
"severity": 1,
|
||||||
|
"file": 2,
|
||||||
|
"message": 3,
|
||||||
|
"line": 4,
|
||||||
|
"column": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "Changes detected. Starting compilation",
|
||||||
|
"endsPattern": "Build done @"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"isBackground": true,
|
||||||
|
"group": "build",
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Develop Cast",
|
||||||
|
"type": "gulp",
|
||||||
|
"task": "develop-cast",
|
||||||
|
"problemMatcher": {
|
||||||
|
"owner": "ha-build",
|
||||||
|
"source": "ha-build",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"severity": "error",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
|
||||||
|
"severity": 1,
|
||||||
|
"file": 2,
|
||||||
|
"message": 3,
|
||||||
|
"line": 4,
|
||||||
|
"column": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "Changes detected. Starting compilation",
|
||||||
|
"endsPattern": "Build done @"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"isBackground": true,
|
||||||
|
"group": "build",
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Run HA Core in devcontainer",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "script/core",
|
||||||
|
"isBackground": true,
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Run HA Core for Supervisor in devcontainer",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "HASSIO=${input:supervisorHost} HASSIO_TOKEN=${input:supervisorToken} script/core",
|
||||||
|
"isBackground": true,
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"runOptions": {
|
||||||
|
"instanceLimit": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"id": "supervisorHost",
|
||||||
|
"type": "promptString",
|
||||||
|
"description": "The IP of the Supervisor host running the Remote API proxy add-on"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "supervisorToken",
|
||||||
|
"type": "promptString",
|
||||||
|
"description": "The token for the Remote API proxy add-on"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -26,4 +26,4 @@ A complete guide can be found at the following [link](https://www.home-assistant
|
|||||||
|
|
||||||
Home Assistant is open-source and Apache 2 licensed. Feel free to browse the repository, learn and reuse parts in your own projects.
|
Home Assistant is open-source and Apache 2 licensed. Feel free to browse the repository, learn and reuse parts in your own projects.
|
||||||
|
|
||||||
We use [BrowserStack](https://www.browserstack.com) to test Home Assistant on a large variation of devices.
|
We use [BrowserStack](https://www.browserstack.com) to test Home Assistant on a large variety of devices.
|
||||||
|
|||||||
@@ -52,7 +52,13 @@ module.exports.terserOptions = (latestBuild) => ({
|
|||||||
module.exports.babelOptions = ({ latestBuild }) => ({
|
module.exports.babelOptions = ({ latestBuild }) => ({
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: [
|
||||||
!latestBuild && [require("@babel/preset-env").default, { modules: false }],
|
!latestBuild && [
|
||||||
|
require("@babel/preset-env").default,
|
||||||
|
{
|
||||||
|
useBuiltIns: "entry",
|
||||||
|
corejs: "3.6",
|
||||||
|
},
|
||||||
|
],
|
||||||
require("@babel/preset-typescript").default,
|
require("@babel/preset-typescript").default,
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
plugins: [
|
plugins: [
|
||||||
@@ -62,7 +68,8 @@ module.exports.babelOptions = ({ latestBuild }) => ({
|
|||||||
{ loose: true, useBuiltIns: true },
|
{ loose: true, useBuiltIns: true },
|
||||||
],
|
],
|
||||||
// Only support the syntax, Webpack will handle it.
|
// Only support the syntax, Webpack will handle it.
|
||||||
"@babel/syntax-dynamic-import",
|
"@babel/plugin-syntax-import-meta",
|
||||||
|
"@babel/plugin-syntax-dynamic-import",
|
||||||
"@babel/plugin-proposal-optional-chaining",
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ const gulp = require("gulp");
|
|||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const foreach = require("gulp-foreach");
|
const foreach = require("gulp-foreach");
|
||||||
const merge = require("gulp-merge-json");
|
const merge = require("gulp-merge-json");
|
||||||
const minify = require("gulp-jsonminify");
|
|
||||||
const rename = require("gulp-rename");
|
const rename = require("gulp-rename");
|
||||||
const transform = require("gulp-json-transform");
|
const transform = require("gulp-json-transform");
|
||||||
const { mapFiles } = require("../util");
|
const { mapFiles } = require("../util");
|
||||||
@@ -301,7 +300,6 @@ gulp.task("build-flattened-translations", function () {
|
|||||||
return flatten(data);
|
return flatten(data);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.pipe(minify())
|
|
||||||
.pipe(
|
.pipe(
|
||||||
rename((filePath) => {
|
rename((filePath) => {
|
||||||
if (filePath.dirname === "core") {
|
if (filePath.dirname === "core") {
|
||||||
|
|||||||
@@ -18,6 +18,14 @@ const bothBuilds = (createConfigFunc, params) => [
|
|||||||
createConfigFunc({ ...params, latestBuild: false }),
|
createConfigFunc({ ...params, latestBuild: false }),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{
|
||||||
|
* compiler: import("webpack").Compiler,
|
||||||
|
* contentBase: string,
|
||||||
|
* port: number,
|
||||||
|
* listenHost?: string
|
||||||
|
* }}
|
||||||
|
*/
|
||||||
const runDevServer = ({
|
const runDevServer = ({
|
||||||
compiler,
|
compiler,
|
||||||
contentBase,
|
contentBase,
|
||||||
@@ -33,7 +41,10 @@ const runDevServer = ({
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
// Server listening
|
// Server listening
|
||||||
log("[webpack-dev-server]", `http://localhost:${port}`);
|
log(
|
||||||
|
"[webpack-dev-server]",
|
||||||
|
`Project is running at http://localhost:${port}`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handler = (done) => (err, stats) => {
|
const handler = (done) => (err, stats) => {
|
||||||
@@ -45,12 +56,12 @@ const handler = (done) => (err, stats) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(`Build done @ ${new Date().toLocaleTimeString()}`);
|
|
||||||
|
|
||||||
if (stats.hasErrors() || stats.hasWarnings()) {
|
if (stats.hasErrors() || stats.hasWarnings()) {
|
||||||
log.warn(stats.toString("minimal"));
|
console.log(stats.toString("minimal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(`Build done @ ${new Date().toLocaleTimeString()}`);
|
||||||
|
|
||||||
if (done) {
|
if (done) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
polymer_dir: path.resolve(__dirname, ".."),
|
polymer_dir: path.resolve(__dirname, ".."),
|
||||||
|
|||||||
@@ -2,9 +2,23 @@ const webpack = require("webpack");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
const ManifestPlugin = require("webpack-manifest-plugin");
|
const ManifestPlugin = require("webpack-manifest-plugin");
|
||||||
const WorkerPlugin = require("worker-plugin");
|
|
||||||
const paths = require("./paths.js");
|
const paths = require("./paths.js");
|
||||||
const bundle = require("./bundle");
|
const bundle = require("./bundle");
|
||||||
|
const log = require("fancy-log");
|
||||||
|
|
||||||
|
class LogStartCompilePlugin {
|
||||||
|
ignoredFirst = false;
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.beforeCompile.tap("LogStartCompilePlugin", () => {
|
||||||
|
if (!this.ignoredFirst) {
|
||||||
|
this.ignoredFirst = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log("Changes detected. Starting compilation");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const createWebpackConfig = ({
|
const createWebpackConfig = ({
|
||||||
entry,
|
entry,
|
||||||
@@ -30,7 +44,7 @@ const createWebpackConfig = ({
|
|||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.js$|\.ts$/,
|
test: /\.m?js$|\.ts$/,
|
||||||
exclude: bundle.babelExclude(),
|
exclude: bundle.babelExclude(),
|
||||||
use: {
|
use: {
|
||||||
loader: "babel-loader",
|
loader: "babel-loader",
|
||||||
@@ -46,16 +60,13 @@ const createWebpackConfig = ({
|
|||||||
optimization: {
|
optimization: {
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new TerserPlugin({
|
new TerserPlugin({
|
||||||
cache: true,
|
|
||||||
parallel: true,
|
parallel: true,
|
||||||
extractComments: true,
|
extractComments: true,
|
||||||
sourceMap: true,
|
|
||||||
terserOptions: bundle.terserOptions(latestBuild),
|
terserOptions: bundle.terserOptions(latestBuild),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new WorkerPlugin(),
|
|
||||||
new ManifestPlugin({
|
new ManifestPlugin({
|
||||||
// Only include the JS of entrypoints
|
// Only include the JS of entrypoints
|
||||||
filter: (file) => file.isInitial && !file.name.endsWith(".map"),
|
filter: (file) => file.isInitial && !file.name.endsWith(".map"),
|
||||||
@@ -99,7 +110,17 @@ const createWebpackConfig = ({
|
|||||||
new RegExp(bundle.emptyPackages({ latestBuild }).join("|")),
|
new RegExp(bundle.emptyPackages({ latestBuild }).join("|")),
|
||||||
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
path.resolve(paths.polymer_dir, "src/util/empty.js")
|
||||||
),
|
),
|
||||||
],
|
// We need to change the import of the polyfill for EventTarget, so we replace the polyfill file with our customized one
|
||||||
|
new webpack.NormalModuleReplacementPlugin(
|
||||||
|
new RegExp(
|
||||||
|
require.resolve(
|
||||||
|
"lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
path.resolve(paths.polymer_dir, "src/resources/EventTarget-ponyfill.js")
|
||||||
|
),
|
||||||
|
!isProdBuild && new LogStartCompilePlugin(),
|
||||||
|
].filter(Boolean),
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: [".ts", ".js", ".json"],
|
extensions: [".ts", ".js", ".json"],
|
||||||
},
|
},
|
||||||
@@ -110,6 +131,22 @@ const createWebpackConfig = ({
|
|||||||
}
|
}
|
||||||
return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
|
return `${chunk.name}.${chunk.hash.substr(0, 8)}.js`;
|
||||||
},
|
},
|
||||||
|
environment: {
|
||||||
|
// The environment supports arrow functions ('() => { ... }').
|
||||||
|
arrowFunction: latestBuild,
|
||||||
|
// The environment supports BigInt as literal (123n).
|
||||||
|
bigIntLiteral: false,
|
||||||
|
// The environment supports const and let for variable declarations.
|
||||||
|
const: latestBuild,
|
||||||
|
// The environment supports destructuring ('{ a, b } = obj').
|
||||||
|
destructuring: latestBuild,
|
||||||
|
// The environment supports an async import() function to import EcmaScript modules.
|
||||||
|
dynamicImport: latestBuild,
|
||||||
|
// The environment supports 'for of' iteration ('for (const x of array) { ... }').
|
||||||
|
forOf: latestBuild,
|
||||||
|
// The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
|
||||||
|
module: latestBuild,
|
||||||
|
},
|
||||||
chunkFilename:
|
chunkFilename:
|
||||||
isProdBuild && !isStatsBuild
|
isProdBuild && !isStatsBuild
|
||||||
? "chunk.[chunkhash].js"
|
? "chunk.[chunkhash].js"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
@@ -212,13 +212,8 @@
|
|||||||
Chromecast is a technology developed by Google, and is available on:
|
Chromecast is a technology developed by Google, and is available on:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Google Chrome (all platforms except on iOS)</li>
|
<li>Google Chrome (all platforms except iOS)</li>
|
||||||
<li>
|
<li>Microsoft Edge (all platforms)</li>
|
||||||
Microsoft Edge (all platforms,
|
|
||||||
<a href="https://www.microsoftedgeinsider.com" target="_blank"
|
|
||||||
>dev and canary builds only</a
|
|
||||||
>)
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class HcLayout extends LitElement {
|
|||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<img class="hero" src="/images/google-nest-hub.png" />
|
<img class="hero" src="/images/google-nest-hub.png" />
|
||||||
<div class="card-header">
|
<h1 class="card-header">
|
||||||
Home Assistant Cast${this.subtitle ? ` – ${this.subtitle}` : ""}
|
Home Assistant Cast${this.subtitle ? ` – ${this.subtitle}` : ""}
|
||||||
${this.auth
|
${this.auth
|
||||||
? html`
|
? html`
|
||||||
@@ -44,7 +44,7 @@ class HcLayout extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</h1>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
|||||||
@@ -6,13 +6,60 @@ import { castContext } from "./cast_context";
|
|||||||
import { HcMain } from "./layout/hc-main";
|
import { HcMain } from "./layout/hc-main";
|
||||||
import { ReceivedMessage } from "./types";
|
import { ReceivedMessage } from "./types";
|
||||||
|
|
||||||
const controller = new HcMain();
|
const lovelaceController = new HcMain();
|
||||||
document.body.append(controller);
|
document.body.append(lovelaceController);
|
||||||
|
|
||||||
|
const mediaPlayer = document.createElement("cast-media-player");
|
||||||
|
mediaPlayer.style.display = "none";
|
||||||
|
document.body.append(mediaPlayer);
|
||||||
|
const playerStylesAdded = false;
|
||||||
|
|
||||||
|
let controls: HTMLElement | null;
|
||||||
|
|
||||||
|
const setTouchControlsVisibility = (visible: boolean) => {
|
||||||
|
if (!castContext.getDeviceCapabilities().touch_input_supported) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
controls =
|
||||||
|
controls ||
|
||||||
|
(document.body.querySelector("touch-controls") as HTMLElement | null);
|
||||||
|
if (controls) {
|
||||||
|
controls.style.display = visible ? "initial" : "none";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const showLovelaceController = () => {
|
||||||
|
mediaPlayer.style.display = "none";
|
||||||
|
lovelaceController.style.display = "initial";
|
||||||
|
document.body.setAttribute("style", "overflow-y: auto !important");
|
||||||
|
setTouchControlsVisibility(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showMediaPlayer = () => {
|
||||||
|
lovelaceController.style.display = "none";
|
||||||
|
mediaPlayer.style.display = "initial";
|
||||||
|
document.body.removeAttribute("style");
|
||||||
|
setTouchControlsVisibility(true);
|
||||||
|
if (!playerStylesAdded) {
|
||||||
|
const style = document.createElement("style");
|
||||||
|
style.innerHTML = `
|
||||||
|
body {
|
||||||
|
--logo-image: url('https://www.home-assistant.io/images/home-assistant-logo.svg');
|
||||||
|
--logo-repeat: no-repeat;
|
||||||
|
--playback-logo-image: url('https://www.home-assistant.io/images/home-assistant-logo.svg');
|
||||||
|
--theme-hue: 200;
|
||||||
|
--progress-color: #03a9f4;
|
||||||
|
--splash-image: url('https://home-assistant.io/images/cast/splash.png');
|
||||||
|
--splash-size: cover;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const options = new cast.framework.CastReceiverOptions();
|
const options = new cast.framework.CastReceiverOptions();
|
||||||
options.disableIdleTimeout = true;
|
options.disableIdleTimeout = true;
|
||||||
options.customNamespaces = {
|
options.customNamespaces = {
|
||||||
// @ts-ignore
|
|
||||||
[CAST_NS]: cast.framework.system.MessageType.JSON,
|
[CAST_NS]: cast.framework.system.MessageType.JSON,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,13 +77,61 @@ options.uiConfig = new cast.framework.ui.UiConfig();
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
options.uiConfig.touchScreenOptimizedApp = true;
|
options.uiConfig.touchScreenOptimizedApp = true;
|
||||||
|
|
||||||
|
castContext.setInactivityTimeout(86400); // 1 day
|
||||||
|
|
||||||
castContext.addCustomMessageListener(
|
castContext.addCustomMessageListener(
|
||||||
CAST_NS,
|
CAST_NS,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
(ev: ReceivedMessage<HassMessage>) => {
|
(ev: ReceivedMessage<HassMessage>) => {
|
||||||
|
// We received a show Lovelace command, stop media from playing, hide media player and show Lovelace controller
|
||||||
|
if (
|
||||||
|
playerManager.getPlayerState() !==
|
||||||
|
cast.framework.messages.PlayerState.IDLE
|
||||||
|
) {
|
||||||
|
playerManager.stop();
|
||||||
|
} else {
|
||||||
|
showLovelaceController();
|
||||||
|
}
|
||||||
const msg = ev.data;
|
const msg = ev.data;
|
||||||
msg.senderId = ev.senderId;
|
msg.senderId = ev.senderId;
|
||||||
controller.processIncomingMessage(msg);
|
lovelaceController.processIncomingMessage(msg);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const playerManager = castContext.getPlayerManager();
|
||||||
|
|
||||||
|
playerManager.setMessageInterceptor(
|
||||||
|
cast.framework.messages.MessageType.LOAD,
|
||||||
|
(loadRequestData) => {
|
||||||
|
// We received a play media command, hide Lovelace and show media player
|
||||||
|
showMediaPlayer();
|
||||||
|
const media = loadRequestData.media;
|
||||||
|
// Special handling if it came from Google Assistant
|
||||||
|
if (media.entity) {
|
||||||
|
media.contentId = media.entity;
|
||||||
|
media.streamType = cast.framework.messages.StreamType.LIVE;
|
||||||
|
media.contentType = "application/vnd.apple.mpegurl";
|
||||||
|
// @ts-ignore
|
||||||
|
media.hlsVideoSegmentFormat =
|
||||||
|
cast.framework.messages.HlsVideoSegmentFormat.FMP4;
|
||||||
|
}
|
||||||
|
return loadRequestData;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
playerManager.addEventListener(
|
||||||
|
cast.framework.events.EventType.MEDIA_STATUS,
|
||||||
|
(event) => {
|
||||||
|
if (
|
||||||
|
event.mediaStatus?.playerState ===
|
||||||
|
cast.framework.messages.PlayerState.IDLE &&
|
||||||
|
event.mediaStatus?.idleReason &&
|
||||||
|
event.mediaStatus?.idleReason !==
|
||||||
|
cast.framework.messages.IdleReason.INTERRUPTED
|
||||||
|
) {
|
||||||
|
// media finished or stopped, return to default Lovelace
|
||||||
|
showLovelaceController();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||||
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 "../../../../src/panels/lovelace/views/hui-view";
|
||||||
import { HomeAssistant } from "../../../../src/types";
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
import "./hc-launch-screen";
|
import "./hc-launch-screen";
|
||||||
@@ -45,22 +44,13 @@ class HcLovelace extends LitElement {
|
|||||||
deleteConfig: async () => undefined,
|
deleteConfig: async () => undefined,
|
||||||
setEditMode: () => undefined,
|
setEditMode: () => undefined,
|
||||||
};
|
};
|
||||||
return this.lovelaceConfig.views[index].panel
|
return html`
|
||||||
? html`
|
<hui-view
|
||||||
<hui-panel-view
|
.hass=${this.hass}
|
||||||
.hass=${this.hass}
|
.lovelace=${lovelace}
|
||||||
.lovelace=${lovelace}
|
.index=${index}
|
||||||
.config=${this.lovelaceConfig.views[index]}
|
></hui-view>
|
||||||
></hui-panel-view>
|
`;
|
||||||
`
|
|
||||||
: html`
|
|
||||||
<hui-view
|
|
||||||
.hass=${this.hass}
|
|
||||||
.lovelace=${lovelace}
|
|
||||||
.index=${index}
|
|
||||||
columns="2"
|
|
||||||
></hui-view>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps) {
|
protected updated(changedProps) {
|
||||||
@@ -76,7 +66,7 @@ class HcLovelace extends LitElement {
|
|||||||
|
|
||||||
if (configBackground) {
|
if (configBackground) {
|
||||||
(this.shadowRoot!.querySelector(
|
(this.shadowRoot!.querySelector(
|
||||||
"hui-view, hui-panel-view"
|
"hui-view"
|
||||||
) as HTMLElement)!.style.setProperty(
|
) as HTMLElement)!.style.setProperty(
|
||||||
"--lovelace-background",
|
"--lovelace-background",
|
||||||
configBackground
|
configBackground
|
||||||
|
|||||||
@@ -216,9 +216,7 @@ export class HcMain extends HassElement {
|
|||||||
}
|
}
|
||||||
this._showDemo = false;
|
this._showDemo = false;
|
||||||
this._lovelacePath = msg.viewPath;
|
this._lovelacePath = msg.viewPath;
|
||||||
if (castContext.getDeviceCapabilities().touch_input_supported) {
|
|
||||||
this._breakFree();
|
|
||||||
}
|
|
||||||
this._sendStatus();
|
this._sendStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,9 +239,6 @@ export class HcMain extends HassElement {
|
|||||||
this._showDemo = true;
|
this._showDemo = true;
|
||||||
this._lovelacePath = "overview";
|
this._lovelacePath = "overview";
|
||||||
this._sendStatus();
|
this._sendStatus();
|
||||||
if (castContext.getDeviceCapabilities().touch_input_supported) {
|
|
||||||
this._breakFree();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,14 +259,6 @@ export class HcMain extends HassElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _breakFree() {
|
|
||||||
const controls = document.body.querySelector("touch-controls");
|
|
||||||
if (controls) {
|
|
||||||
controls.remove();
|
|
||||||
}
|
|
||||||
document.body.setAttribute("style", "overflow-y: auto !important");
|
|
||||||
}
|
|
||||||
|
|
||||||
private sendMessage(senderId: string, response: any) {
|
private sendMessage(senderId: string, response: any) {
|
||||||
castContext.sendCustomMessage(CAST_NS, senderId, response);
|
castContext.sendCustomMessage(CAST_NS, senderId, response);
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 767 B After Width: | Height: | Size: 532 B |
|
Before Width: | Height: | Size: 803 B After Width: | Height: | Size: 535 B |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 375 B After Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
@@ -7,205 +7,183 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
|||||||
cards: [
|
cards: [
|
||||||
{ type: "custom:ha-demo-card" },
|
{ type: "custom:ha-demo-card" },
|
||||||
{
|
{
|
||||||
|
type: "grid",
|
||||||
|
columns: 4,
|
||||||
cards: [
|
cards: [
|
||||||
{
|
{
|
||||||
cards: [
|
image: "/assets/teachingbirds/isa_square.jpg",
|
||||||
|
type: "picture-entity",
|
||||||
|
show_name: false,
|
||||||
|
tap_action: {
|
||||||
|
action: "more-info",
|
||||||
|
},
|
||||||
|
entity: "sensor.presence_isa",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: "/assets/teachingbirds/Stefan_square.jpg",
|
||||||
|
type: "picture-entity",
|
||||||
|
show_name: false,
|
||||||
|
tap_action: {
|
||||||
|
action: "more-info",
|
||||||
|
},
|
||||||
|
entity: "sensor.presence_stefan",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: "/assets/teachingbirds/background_square.png",
|
||||||
|
elements: [
|
||||||
{
|
{
|
||||||
image: "/assets/teachingbirds/isa_square.jpg",
|
state_image: {
|
||||||
type: "picture-entity",
|
on: "/assets/teachingbirds/radiator_on.jpg",
|
||||||
show_name: false,
|
off: "/assets/teachingbirds/radiator_off.jpg",
|
||||||
|
},
|
||||||
|
type: "image",
|
||||||
|
style: {
|
||||||
|
width: "100%",
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
},
|
||||||
tap_action: {
|
tap_action: {
|
||||||
action: "more-info",
|
action: "more-info",
|
||||||
},
|
},
|
||||||
entity: "sensor.presence_isa",
|
entity: "switch.stefan_radiator_3",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: "/assets/teachingbirds/Stefan_square.jpg",
|
style: {
|
||||||
type: "picture-entity",
|
top: "90%",
|
||||||
show_name: false,
|
left: "50%",
|
||||||
tap_action: {
|
|
||||||
action: "more-info",
|
|
||||||
},
|
},
|
||||||
entity: "sensor.presence_stefan",
|
type: "state-label",
|
||||||
},
|
|
||||||
{
|
|
||||||
image: "/assets/teachingbirds/background_square.png",
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
state_image: {
|
|
||||||
on: "/assets/teachingbirds/radiator_on.jpg",
|
|
||||||
off: "/assets/teachingbirds/radiator_off.jpg",
|
|
||||||
},
|
|
||||||
type: "image",
|
|
||||||
style: {
|
|
||||||
width: "100%",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
},
|
|
||||||
tap_action: {
|
|
||||||
action: "more-info",
|
|
||||||
},
|
|
||||||
entity: "switch.stefan_radiator_3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
top: "90%",
|
|
||||||
left: "50%",
|
|
||||||
},
|
|
||||||
type: "state-label",
|
|
||||||
entity: "sensor.temperature_stefan",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "picture-elements",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: "/assets/teachingbirds/background_square.png",
|
|
||||||
elements: [
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
"--mdc-icon-size": "100%",
|
|
||||||
top: "50%",
|
|
||||||
left: "50%",
|
|
||||||
},
|
|
||||||
type: "icon",
|
|
||||||
tap_action: {
|
|
||||||
action: "navigate",
|
|
||||||
navigation_path: "/lovelace/home_info",
|
|
||||||
},
|
|
||||||
icon: "mdi:car",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "picture-elements",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "horizontal-stack",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cards: [
|
|
||||||
{
|
|
||||||
show_name: false,
|
|
||||||
type: "picture-entity",
|
|
||||||
name: "Alarm",
|
|
||||||
image: "/assets/teachingbirds/House_square.jpg",
|
|
||||||
entity: "alarm_control_panel.house",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Roomba",
|
|
||||||
image: "/assets/teachingbirds/roomba_square.jpg",
|
|
||||||
show_name: false,
|
|
||||||
type: "picture-entity",
|
|
||||||
state_image: {
|
|
||||||
"Not Today": "/assets/teachingbirds/roomba_bw_square.jpg",
|
|
||||||
},
|
|
||||||
entity: "input_select.roomba_mode",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
show_name: false,
|
|
||||||
type: "picture-entity",
|
|
||||||
state_image: {
|
|
||||||
Mail: "/assets/teachingbirds/mailbox_square.jpg",
|
|
||||||
"Package and mail":
|
|
||||||
"/assets/teachingbirds/mailbox_square.jpg",
|
|
||||||
Empty: "/assets/teachingbirds/mailbox_bw_square.jpg",
|
|
||||||
Package: "/assets/teachingbirds/mailbox_square.jpg",
|
|
||||||
},
|
|
||||||
entity: "sensor.mailbox",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
show_name: false,
|
|
||||||
state_image: {
|
|
||||||
"Put out": "/assets/teachingbirds/trash_square.jpg",
|
|
||||||
"Take in": "/assets/teachingbirds/trash_square.jpg",
|
|
||||||
},
|
|
||||||
type: "picture-entity",
|
|
||||||
image: "/assets/teachingbirds/trash_bear_bw_square.jpg",
|
|
||||||
entity: "sensor.trash_status",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "horizontal-stack",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cards: [
|
|
||||||
{
|
|
||||||
state_image: {
|
|
||||||
Idle: "/assets/teachingbirds/washer_square.jpg",
|
|
||||||
Running: "/assets/teachingbirds/laundry_running_square.jpg",
|
|
||||||
Clean: "/assets/teachingbirds/laundry_clean_2_square.jpg",
|
|
||||||
},
|
|
||||||
entity: "input_select.washing_machine_status",
|
|
||||||
type: "picture-entity",
|
|
||||||
show_name: false,
|
|
||||||
name: "Washer",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
state_image: {
|
|
||||||
Idle: "/assets/teachingbirds/dryer_square.jpg",
|
|
||||||
Running: "/assets/teachingbirds/clothes_drying_square.jpg",
|
|
||||||
Clean: "/assets/teachingbirds/folded_clothes_square.jpg",
|
|
||||||
},
|
|
||||||
entity: "input_select.dryer_status",
|
|
||||||
type: "picture-entity",
|
|
||||||
show_name: false,
|
|
||||||
name: "Dryer",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: "/assets/teachingbirds/guests_square.jpg",
|
|
||||||
type: "picture-entity",
|
|
||||||
show_name: false,
|
|
||||||
tap_action: {
|
|
||||||
action: "toggle",
|
|
||||||
},
|
|
||||||
entity: "input_boolean.guest_mode",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: "/assets/teachingbirds/cleaning_square.jpg",
|
|
||||||
type: "picture-entity",
|
|
||||||
show_name: false,
|
|
||||||
tap_action: {
|
|
||||||
action: "toggle",
|
|
||||||
},
|
|
||||||
entity: "input_boolean.cleaning_day",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "horizontal-stack",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "vertical-stack",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "vertical-stack",
|
|
||||||
cards: [
|
|
||||||
{
|
|
||||||
cards: [
|
|
||||||
{
|
|
||||||
graph: "line",
|
|
||||||
type: "sensor",
|
|
||||||
entity: "sensor.temperature_bedroom",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
graph: "line",
|
|
||||||
type: "sensor",
|
|
||||||
name: "S's room",
|
|
||||||
entity: "sensor.temperature_stefan",
|
entity: "sensor.temperature_stefan",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
type: "horizontal-stack",
|
type: "picture-elements",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cards: [
|
image: "/assets/teachingbirds/background_square.png",
|
||||||
|
elements: [
|
||||||
{
|
{
|
||||||
graph: "line",
|
style: {
|
||||||
type: "sensor",
|
"--mdc-icon-size": "100%",
|
||||||
entity: "sensor.temperature_passage",
|
top: "50%",
|
||||||
},
|
left: "50%",
|
||||||
{
|
},
|
||||||
graph: "line",
|
type: "icon",
|
||||||
type: "sensor",
|
tap_action: {
|
||||||
name: "Laundry",
|
action: "navigate",
|
||||||
entity: "sensor.temperature_downstairs_bathroom",
|
navigation_path: "/lovelace/home_info",
|
||||||
|
},
|
||||||
|
icon: "mdi:car",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
type: "horizontal-stack",
|
type: "picture-elements",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
show_name: false,
|
||||||
|
type: "picture-entity",
|
||||||
|
name: "Alarm",
|
||||||
|
image: "/assets/teachingbirds/House_square.jpg",
|
||||||
|
entity: "alarm_control_panel.house",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Roomba",
|
||||||
|
image: "/assets/teachingbirds/roomba_square.jpg",
|
||||||
|
show_name: false,
|
||||||
|
type: "picture-entity",
|
||||||
|
state_image: {
|
||||||
|
"Not Today": "/assets/teachingbirds/roomba_bw_square.jpg",
|
||||||
|
},
|
||||||
|
entity: "input_select.roomba_mode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
show_name: false,
|
||||||
|
type: "picture-entity",
|
||||||
|
state_image: {
|
||||||
|
Mail: "/assets/teachingbirds/mailbox_square.jpg",
|
||||||
|
"Package and mail": "/assets/teachingbirds/mailbox_square.jpg",
|
||||||
|
Empty: "/assets/teachingbirds/mailbox_bw_square.jpg",
|
||||||
|
Package: "/assets/teachingbirds/mailbox_square.jpg",
|
||||||
|
},
|
||||||
|
entity: "sensor.mailbox",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
show_name: false,
|
||||||
|
state_image: {
|
||||||
|
"Put out": "/assets/teachingbirds/trash_square.jpg",
|
||||||
|
"Take in": "/assets/teachingbirds/trash_square.jpg",
|
||||||
|
},
|
||||||
|
type: "picture-entity",
|
||||||
|
image: "/assets/teachingbirds/trash_bear_bw_square.jpg",
|
||||||
|
entity: "sensor.trash_status",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
state_image: {
|
||||||
|
Idle: "/assets/teachingbirds/washer_square.jpg",
|
||||||
|
Running: "/assets/teachingbirds/laundry_running_square.jpg",
|
||||||
|
Clean: "/assets/teachingbirds/laundry_clean_2_square.jpg",
|
||||||
|
},
|
||||||
|
entity: "input_select.washing_machine_status",
|
||||||
|
type: "picture-entity",
|
||||||
|
show_name: false,
|
||||||
|
name: "Washer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
state_image: {
|
||||||
|
Idle: "/assets/teachingbirds/dryer_square.jpg",
|
||||||
|
Running: "/assets/teachingbirds/clothes_drying_square.jpg",
|
||||||
|
Clean: "/assets/teachingbirds/folded_clothes_square.jpg",
|
||||||
|
},
|
||||||
|
entity: "input_select.dryer_status",
|
||||||
|
type: "picture-entity",
|
||||||
|
show_name: false,
|
||||||
|
name: "Dryer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: "/assets/teachingbirds/guests_square.jpg",
|
||||||
|
type: "picture-entity",
|
||||||
|
show_name: false,
|
||||||
|
tap_action: {
|
||||||
|
action: "toggle",
|
||||||
|
},
|
||||||
|
entity: "input_boolean.guest_mode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: "/assets/teachingbirds/cleaning_square.jpg",
|
||||||
|
type: "picture-entity",
|
||||||
|
show_name: false,
|
||||||
|
tap_action: {
|
||||||
|
action: "toggle",
|
||||||
|
},
|
||||||
|
entity: "input_boolean.cleaning_day",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "grid",
|
||||||
|
columns: 2,
|
||||||
|
cards: [
|
||||||
|
{
|
||||||
|
graph: "line",
|
||||||
|
type: "sensor",
|
||||||
|
entity: "sensor.temperature_bedroom",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
graph: "line",
|
||||||
|
type: "sensor",
|
||||||
|
name: "S's room",
|
||||||
|
entity: "sensor.temperature_stefan",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
graph: "line",
|
||||||
|
type: "sensor",
|
||||||
|
entity: "sensor.temperature_passage",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
graph: "line",
|
||||||
|
type: "sensor",
|
||||||
|
name: "Laundry",
|
||||||
|
entity: "sensor.temperature_downstairs_bathroom",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,4 +6,11 @@ export const mockTemplate = (hass: MockHomeAssistant) => {
|
|||||||
body: { message: "Template dev tool does not work in the demo." },
|
body: { message: "Template dev tool does not work in the demo." },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
hass.mockWS("render_template", (msg, onChange) => {
|
||||||
|
onChange!({
|
||||||
|
result: msg.template,
|
||||||
|
listeners: { all: false, domains: [], entities: [], time: false },
|
||||||
|
});
|
||||||
|
return () => {};
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 110 KiB |
BIN
gallery/public/images/sunflowers.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
@@ -5,11 +5,16 @@ import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|||||||
import "../../../src/components/ha-switch";
|
import "../../../src/components/ha-switch";
|
||||||
import "../../../src/components/ha-formfield";
|
import "../../../src/components/ha-formfield";
|
||||||
import "./demo-card";
|
import "./demo-card";
|
||||||
|
import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element";
|
||||||
|
|
||||||
class DemoCards extends PolymerElement {
|
class DemoCards extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
|
#container {
|
||||||
|
min-height: calc(100vh - 128px);
|
||||||
|
background: var(--primary-background-color);
|
||||||
|
}
|
||||||
.cards {
|
.cards {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@@ -24,6 +29,9 @@ class DemoCards extends PolymerElement {
|
|||||||
.filters {
|
.filters {
|
||||||
margin-left: 60px;
|
margin-left: 60px;
|
||||||
}
|
}
|
||||||
|
ha-formfield {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<app-toolbar>
|
<app-toolbar>
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
@@ -31,16 +39,21 @@ class DemoCards extends PolymerElement {
|
|||||||
<ha-switch checked="[[_showConfig]]" on-change="_showConfigToggled">
|
<ha-switch checked="[[_showConfig]]" on-change="_showConfigToggled">
|
||||||
</ha-switch>
|
</ha-switch>
|
||||||
</ha-formfield>
|
</ha-formfield>
|
||||||
|
<ha-formfield label="Dark theme">
|
||||||
|
<ha-switch on-change="_darkThemeToggled"> </ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
</div>
|
</div>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
<div class="cards">
|
<div id="container">
|
||||||
<template is="dom-repeat" items="[[configs]]">
|
<div class="cards">
|
||||||
<demo-card
|
<template is="dom-repeat" items="[[configs]]">
|
||||||
config="[[item]]"
|
<demo-card
|
||||||
show-config="[[_showConfig]]"
|
config="[[item]]"
|
||||||
hass="[[hass]]"
|
show-config="[[_showConfig]]"
|
||||||
></demo-card>
|
hass="[[hass]]"
|
||||||
</template>
|
></demo-card>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -59,6 +72,12 @@ class DemoCards extends PolymerElement {
|
|||||||
_showConfigToggled(ev) {
|
_showConfigToggled(ev) {
|
||||||
this._showConfig = ev.target.checked;
|
this._showConfig = ev.target.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_darkThemeToggled(ev) {
|
||||||
|
applyThemesOnElement(this.$.container, { themes: {} }, "default", {
|
||||||
|
dark: ev.target.checked,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-cards", DemoCards);
|
customElements.define("demo-cards", DemoCards);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
|
|||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import "../../../src/components/ha-card";
|
import "../../../src/components/ha-card";
|
||||||
import "../../../src/state-summary/state-card-content";
|
import "../../../src/state-summary/state-card-content";
|
||||||
import "./more-info-content";
|
import "../../../src/dialogs/more-info/more-info-content";
|
||||||
|
|
||||||
class DemoMoreInfo extends PolymerElement {
|
class DemoMoreInfo extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
@@ -16,15 +16,12 @@ class DemoMoreInfo extends PolymerElement {
|
|||||||
|
|
||||||
ha-card {
|
ha-card {
|
||||||
width: 333px;
|
width: 333px;
|
||||||
|
padding: 20px 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
state-card-content {
|
state-card-content {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
|
||||||
|
|
||||||
more-info-content {
|
|
||||||
padding: 0 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
import { HassEntity } from "home-assistant-js-websocket";
|
|
||||||
import { property, PropertyValues, UpdatingElement } from "lit-element";
|
|
||||||
import dynamicContentUpdater from "../../../src/common/dom/dynamic_content_updater";
|
|
||||||
import { stateMoreInfoType } from "../../../src/common/entity/state_more_info_type";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-alarm_control_panel";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-automation";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-camera";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-climate";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-configurator";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-counter";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-cover";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-default";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-fan";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-group";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-humidifier";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-input_datetime";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-light";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-lock";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-media_player";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-person";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-script";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-sun";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-timer";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-vacuum";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-water_heater";
|
|
||||||
import "../../../src/dialogs/more-info/controls/more-info-weather";
|
|
||||||
import { HomeAssistant } from "../../../src/types";
|
|
||||||
|
|
||||||
class MoreInfoContent extends UpdatingElement {
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@property() public stateObj?: HassEntity;
|
|
||||||
|
|
||||||
private _detachedChild?: ChildNode;
|
|
||||||
|
|
||||||
protected firstUpdated(): void {
|
|
||||||
this.style.position = "relative";
|
|
||||||
this.style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is not a lit element, but an updating element, so we implement update
|
|
||||||
protected update(changedProps: PropertyValues): void {
|
|
||||||
super.update(changedProps);
|
|
||||||
const stateObj = this.stateObj;
|
|
||||||
const hass = this.hass;
|
|
||||||
|
|
||||||
if (!stateObj || !hass) {
|
|
||||||
if (this.lastChild) {
|
|
||||||
this._detachedChild = this.lastChild;
|
|
||||||
// Detach child to prevent it from doing work.
|
|
||||||
this.removeChild(this.lastChild);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._detachedChild) {
|
|
||||||
this.appendChild(this._detachedChild);
|
|
||||||
this._detachedChild = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moreInfoType =
|
|
||||||
stateObj.attributes && "custom_ui_more_info" in stateObj.attributes
|
|
||||||
? stateObj.attributes.custom_ui_more_info
|
|
||||||
: "more-info-" + stateMoreInfoType(stateObj);
|
|
||||||
|
|
||||||
dynamicContentUpdater(this, moreInfoType.toUpperCase(), {
|
|
||||||
hass,
|
|
||||||
stateObj,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("more-info-content", MoreInfoContent);
|
|
||||||
@@ -6,7 +6,9 @@ export const createMediaPlayerEntities = () => [
|
|||||||
media_content_type: "music",
|
media_content_type: "music",
|
||||||
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
|
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
|
||||||
media_artist: "Technohead",
|
media_artist: "Technohead",
|
||||||
supported_features: 64063,
|
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
||||||
|
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
|
||||||
|
supported_features: 195135,
|
||||||
entity_picture: "/images/album_cover_2.jpg",
|
entity_picture: "/images/album_cover_2.jpg",
|
||||||
media_duration: 300,
|
media_duration: 300,
|
||||||
media_position: 50,
|
media_position: 50,
|
||||||
@@ -14,12 +16,15 @@ export const createMediaPlayerEntities = () => [
|
|||||||
// 23 seconds in
|
// 23 seconds in
|
||||||
new Date().getTime() - 23000
|
new Date().getTime() - 23000
|
||||||
).toISOString(),
|
).toISOString(),
|
||||||
|
volume_level: 0.5,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "music_playing", "playing", {
|
getEntity("media_player", "music_playing", "playing", {
|
||||||
friendly_name: "Playing The Music",
|
friendly_name: "Playing The Music",
|
||||||
media_content_type: "music",
|
media_content_type: "music",
|
||||||
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
|
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
|
||||||
media_artist: "Technohead",
|
media_artist: "Technohead",
|
||||||
|
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
||||||
|
// Select Source + Stop + Clear + Play + Shuffle Set
|
||||||
supported_features: 64063,
|
supported_features: 64063,
|
||||||
entity_picture: "/images/album_cover.jpg",
|
entity_picture: "/images/album_cover.jpg",
|
||||||
media_duration: 300,
|
media_duration: 300,
|
||||||
@@ -28,6 +33,7 @@ export const createMediaPlayerEntities = () => [
|
|||||||
// 23 seconds in
|
// 23 seconds in
|
||||||
new Date().getTime() - 23000
|
new Date().getTime() - 23000
|
||||||
).toISOString(),
|
).toISOString(),
|
||||||
|
volume_level: 0.5,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "stream_playing", "playing", {
|
getEntity("media_player", "stream_playing", "playing", {
|
||||||
friendly_name: "Playing the Stream",
|
friendly_name: "Playing the Stream",
|
||||||
@@ -35,50 +41,125 @@ export const createMediaPlayerEntities = () => [
|
|||||||
media_title: "Epic sax guy 10 hours",
|
media_title: "Epic sax guy 10 hours",
|
||||||
app_name: "YouTube",
|
app_name: "YouTube",
|
||||||
entity_picture: "/images/frenck.jpg",
|
entity_picture: "/images/frenck.jpg",
|
||||||
supported_features: 33,
|
// Pause + Next Track + Play + Browse Media
|
||||||
|
supported_features: 147489,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "living_room", "playing", {
|
getEntity("media_player", "stream_paused", "paused", {
|
||||||
friendly_name: "Pause, No skip, tvshow",
|
friendly_name: "Paused the Stream",
|
||||||
|
media_content_type: "movie",
|
||||||
|
media_title: "Epic sax guy 10 hours",
|
||||||
|
app_name: "YouTube",
|
||||||
|
entity_picture: "/images/frenck.jpg",
|
||||||
|
// Pause + Next Track + Play
|
||||||
|
supported_features: 16417,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "stream_playing_previous", "playing", {
|
||||||
|
friendly_name: 'Playing the Stream (with "previous" support)',
|
||||||
|
media_content_type: "movie",
|
||||||
|
media_title: "Epic sax guy 10 hours",
|
||||||
|
app_name: "YouTube",
|
||||||
|
entity_picture: "/images/frenck.jpg",
|
||||||
|
// Pause + Previous Track + Play
|
||||||
|
supported_features: 16401,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "tv_playing", "playing", {
|
||||||
|
friendly_name: "Playing non-skip TV Show",
|
||||||
media_content_type: "tvshow",
|
media_content_type: "tvshow",
|
||||||
media_title: "Chapter 1",
|
media_title: "Chapter 1",
|
||||||
media_series_title: "House of Cards",
|
media_series_title: "House of Cards",
|
||||||
app_name: "Netflix",
|
app_name: "Netflix",
|
||||||
entity_picture: "/images/netflix.jpg",
|
entity_picture: "/images/netflix.jpg",
|
||||||
|
// Pause
|
||||||
supported_features: 1,
|
supported_features: 1,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "sonos_idle", "idle", {
|
getEntity("media_player", "sonos_idle", "idle", {
|
||||||
friendly_name: "Sonos Idle",
|
friendly_name: "Sonos Idle",
|
||||||
|
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
|
||||||
|
// Select Source + Stop + Clear + Play + Shuffle Set
|
||||||
supported_features: 64063,
|
supported_features: 64063,
|
||||||
|
volume_level: 0.33,
|
||||||
|
is_volume_muted: true,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "theater", "off", {
|
getEntity("media_player", "idle_browse_media", "idle", {
|
||||||
|
friendly_name: "Idle waiting for Browse Media (e.g. Spotify)",
|
||||||
|
// Pause + Seek + Volume Set + Previous Track + Next Track + Play Media +
|
||||||
|
// Select Source + Play + Shuffle Set + Browse Media
|
||||||
|
supported_features: 182839,
|
||||||
|
volume_level: 0.79,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "theater_off", "off", {
|
||||||
friendly_name: "TV Off",
|
friendly_name: "TV Off",
|
||||||
|
// On + Off + Play + Next + Pause
|
||||||
|
supported_features: 16801,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "theater_on", "on", {
|
||||||
|
friendly_name: "TV On",
|
||||||
|
// On + Off + Play + Next + Pause
|
||||||
|
supported_features: 16801,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "theater_off_static", "off", {
|
||||||
|
friendly_name: "TV Off (cannot be switched on)",
|
||||||
|
// Off + Next + Pause
|
||||||
|
supported_features: 289,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "theater_on_static", "on", {
|
||||||
|
friendly_name: "TV On (cannot be switched off)",
|
||||||
|
// On + Next + Pause
|
||||||
supported_features: 161,
|
supported_features: 161,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "android_cast", "playing", {
|
getEntity("media_player", "android_cast", "playing", {
|
||||||
friendly_name: "Casting App",
|
friendly_name: "Casting App (no supported features)",
|
||||||
media_title: "Android Screen Casting",
|
media_title: "Android Screen Casting",
|
||||||
app_name: "Screen Mirroring",
|
app_name: "Screen Mirroring",
|
||||||
// supported_features: 21437,
|
}),
|
||||||
|
getEntity("media_player", "image_display", "playing", {
|
||||||
|
friendly_name: "Digital Picture Frame",
|
||||||
|
media_content_type: "image",
|
||||||
|
media_title: "Famous Painting",
|
||||||
|
media_artist: "Famous Artist",
|
||||||
|
entity_picture: "/images/sunflowers.jpg",
|
||||||
|
// On + Off + Browse Media
|
||||||
|
supported_features: 131456,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "unavailable", "unavailable", {
|
getEntity("media_player", "unavailable", "unavailable", {
|
||||||
friendly_name: "Player Unavailable",
|
friendly_name: "Player Unavailable",
|
||||||
|
// Pause + Volume Set + Volume Mute + Previous Track + Next Track +
|
||||||
|
// Play Media + Stop + Play
|
||||||
supported_features: 21437,
|
supported_features: 21437,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "unknown", "unknown", {
|
getEntity("media_player", "unknown", "unknown", {
|
||||||
friendly_name: "Player Unknown",
|
friendly_name: "Player Unknown",
|
||||||
|
// Pause + Volume Set + Volume Mute + Previous Track + Next Track +
|
||||||
|
// Play Media + Stop + Play
|
||||||
supported_features: 21437,
|
supported_features: 21437,
|
||||||
}),
|
}),
|
||||||
|
getEntity("media_player", "playing", "playing", {
|
||||||
|
friendly_name: "Player Playing (no Pause support)",
|
||||||
|
// Volume Set + Volume Mute + Previous Track + Next Track +
|
||||||
|
// Play Media + Stop + Play
|
||||||
|
supported_features: 21436,
|
||||||
|
volume_level: 1,
|
||||||
|
}),
|
||||||
|
getEntity("media_player", "idle", "idle", {
|
||||||
|
friendly_name: "Player Idle",
|
||||||
|
// Pause + Volume Set + Volume Mute + Previous Track + Next Track +
|
||||||
|
// Play Media + Stop + Play
|
||||||
|
supported_features: 21437,
|
||||||
|
volume_level: 0,
|
||||||
|
}),
|
||||||
getEntity("media_player", "receiver_on", "on", {
|
getEntity("media_player", "receiver_on", "on", {
|
||||||
source_list: ["AirPlay", "Blu-Ray", "TV", "USB", "iPod (USB)"],
|
source_list: ["AirPlay", "Blu-Ray", "TV", "USB", "iPod (USB)"],
|
||||||
volume_level: 0.63,
|
volume_level: 0.63,
|
||||||
is_volume_muted: false,
|
is_volume_muted: false,
|
||||||
source: "TV",
|
source: "TV",
|
||||||
friendly_name: "Receiver",
|
friendly_name: "Receiver (selectable sources)",
|
||||||
|
// Volume Set + Volume Mute + On + Off + Select Source + Play + Sound Mode
|
||||||
supported_features: 84364,
|
supported_features: 84364,
|
||||||
}),
|
}),
|
||||||
getEntity("media_player", "receiver_off", "off", {
|
getEntity("media_player", "receiver_off", "off", {
|
||||||
source_list: ["AirPlay", "Blu-Ray", "TV", "USB", "iPod (USB)"],
|
source_list: ["AirPlay", "Blu-Ray", "TV", "USB", "iPod (USB)"],
|
||||||
friendly_name: "Receiver",
|
friendly_name: "Receiver (selectable sources)",
|
||||||
|
// Volume Set + Volume Mute + On + Off + Select Source + Play + Sound Mode
|
||||||
supported_features: 84364,
|
supported_features: 84364,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ const ENTITIES = [
|
|||||||
getEntity("alarm_control_panel", "unavailable", "unavailable", {
|
getEntity("alarm_control_panel", "unavailable", "unavailable", {
|
||||||
friendly_name: "Alarm",
|
friendly_name: "Alarm",
|
||||||
}),
|
}),
|
||||||
|
getEntity("alarm_control_panel", "alarm_code", "disarmed", {
|
||||||
|
friendly_name: "Alarm",
|
||||||
|
code_format: "number",
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@@ -30,7 +34,14 @@ const CONFIGS = [
|
|||||||
config: `
|
config: `
|
||||||
- type: alarm-panel
|
- type: alarm-panel
|
||||||
entity: alarm_control_panel.alarm_armed
|
entity: alarm_control_panel.alarm_armed
|
||||||
title: My Alarm
|
name: My Alarm
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Code Example",
|
||||||
|
config: `
|
||||||
|
- type: alarm-panel
|
||||||
|
entity: alarm_control_panel.alarm_code
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -83,8 +94,12 @@ class DemoAlarmPanelEntity extends PolymerElement {
|
|||||||
|
|
||||||
public ready() {
|
public ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
|
this._setupDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setupDemo() {
|
||||||
const hass = provideHass(this.$.demos);
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
await hass.updateTranslations(null, "en");
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,4 +98,4 @@ class DemoButtonEntity extends PolymerElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-button-card", DemoButtonEntity);
|
customElements.define("demo-hui-entity-button-card", DemoButtonEntity);
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ import "../components/demo-cards";
|
|||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity("sensor", "brightness", "12", {}),
|
getEntity("sensor", "brightness", "12", {}),
|
||||||
|
getEntity("sensor", "brightness_medium", "53", {}),
|
||||||
|
getEntity("sensor", "brightness_high", "87", {}),
|
||||||
getEntity("plant", "bonsai", "ok", {}),
|
getEntity("plant", "bonsai", "ok", {}),
|
||||||
|
getEntity("sensor", "not_working", "unavailable", {}),
|
||||||
getEntity("sensor", "outside_humidity", "54", {
|
getEntity("sensor", "outside_humidity", "54", {
|
||||||
unit_of_measurement: "%",
|
unit_of_measurement: "%",
|
||||||
}),
|
}),
|
||||||
@@ -20,16 +23,10 @@ const CONFIGS = [
|
|||||||
{
|
{
|
||||||
heading: "Basic example",
|
heading: "Basic example",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
|
||||||
entity: sensor.brightness
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
heading: "With title",
|
|
||||||
config: `
|
|
||||||
- type: gauge
|
- type: gauge
|
||||||
title: Humidity
|
title: Humidity
|
||||||
entity: sensor.outside_humidity
|
entity: sensor.outside_humidity
|
||||||
|
name: Outside Humidity
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -38,6 +35,7 @@ const CONFIGS = [
|
|||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.outside_temperature
|
entity: sensor.outside_temperature
|
||||||
unit_of_measurement: C
|
unit_of_measurement: C
|
||||||
|
name: Outside Temperature
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -45,19 +43,45 @@ const CONFIGS = [
|
|||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.brightness
|
entity: sensor.brightness
|
||||||
|
name: Brightness Low
|
||||||
severity:
|
severity:
|
||||||
red: 32
|
red: 75
|
||||||
green: 0
|
green: 0
|
||||||
yellow: 23
|
yellow: 50
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Setting Min and Max Values",
|
heading: "Setting Severity Levels",
|
||||||
|
config: `
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.brightness_medium
|
||||||
|
name: Brightness Medium
|
||||||
|
severity:
|
||||||
|
red: 75
|
||||||
|
green: 0
|
||||||
|
yellow: 50
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Setting Severity Levels",
|
||||||
|
config: `
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.brightness_high
|
||||||
|
name: Brightness High
|
||||||
|
severity:
|
||||||
|
red: 75
|
||||||
|
green: 0
|
||||||
|
yellow: 50
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Setting Min (0) and Max (15) Values",
|
||||||
config: `
|
config: `
|
||||||
- type: gauge
|
- type: gauge
|
||||||
entity: sensor.brightness
|
entity: sensor.brightness
|
||||||
|
name: Brightness
|
||||||
min: 0
|
min: 0
|
||||||
max: 38
|
max: 15
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -74,6 +98,13 @@ const CONFIGS = [
|
|||||||
entity: plant.bonsai
|
entity: plant.bonsai
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: "Unavailable entity",
|
||||||
|
config: `
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.not_working
|
||||||
|
`,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoGaugeEntity extends PolymerElement {
|
class DemoGaugeEntity extends PolymerElement {
|
||||||
|
|||||||
@@ -8,29 +8,43 @@ import "../components/demo-cards";
|
|||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity("light", "bed_light", "on", {
|
getEntity("light", "bed_light", "on", {
|
||||||
friendly_name: "Bed Light",
|
friendly_name: "Bed Light",
|
||||||
brightness: 130,
|
brightness: 255,
|
||||||
}),
|
}),
|
||||||
getEntity("light", "dim", "off", {
|
getEntity("light", "dim_on", "on", {
|
||||||
|
friendly_name: "Dining Room",
|
||||||
|
supported_features: 1,
|
||||||
|
brightness: 100,
|
||||||
|
}),
|
||||||
|
getEntity("light", "dim_off", "off", {
|
||||||
|
friendly_name: "Dining Room",
|
||||||
supported_features: 1,
|
supported_features: 1,
|
||||||
}),
|
}),
|
||||||
getEntity("light", "unavailable", "unavailable", {
|
getEntity("light", "unavailable", "unavailable", {
|
||||||
|
friendly_name: "Lost Light",
|
||||||
supported_features: 1,
|
supported_features: 1,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: "Basic example",
|
heading: "Switchable Light",
|
||||||
config: `
|
config: `
|
||||||
- type: light
|
- type: light
|
||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Dim",
|
heading: "Dimmable Light On",
|
||||||
config: `
|
config: `
|
||||||
- type: light
|
- type: light
|
||||||
entity: light.dim
|
entity: light.dim_on
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Dimmable Light Off",
|
||||||
|
config: `
|
||||||
|
- type: light
|
||||||
|
entity: light.dim_off
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
|
import { mockTemplate } from "../../../demo/src/stubs/template";
|
||||||
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@@ -254,7 +256,7 @@ const CONFIGS = [
|
|||||||
|
|
||||||
class DemoMarkdown extends PolymerElement {
|
class DemoMarkdown extends PolymerElement {
|
||||||
static get template() {
|
static get template() {
|
||||||
return html` <demo-cards configs="[[_configs]]"></demo-cards> `;
|
return html` <demo-cards id="demos" configs="[[_configs]]"></demo-cards> `;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@@ -265,6 +267,12 @@ class DemoMarkdown extends PolymerElement {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
|
mockTemplate(hass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("demo-hui-markdown-card", DemoMarkdown);
|
customElements.define("demo-hui-markdown-card", DemoMarkdown);
|
||||||
|
|||||||
@@ -7,40 +7,61 @@ import { createMediaPlayerEntities } from "../data/media_players";
|
|||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
{
|
{
|
||||||
heading: "Paused music",
|
heading: "Paused Music",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.music_paused
|
entity: media_player.music_paused
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Playing music",
|
heading: "Playing Music",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.music_playing
|
entity: media_player.music_playing
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Playing stream",
|
heading: "Playing Stream",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.stream_playing
|
entity: media_player.stream_playing
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Pause, No skip, tvshow",
|
heading: "Paused Stream",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.living_room
|
entity: media_player.stream_paused
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Screen casting",
|
heading: 'Playing Stream (with "previous" support)',
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.stream_playing_previous
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Playing non-skip TV Show",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.tv_playing
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Screen Casting",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.android_cast
|
entity: media_player.android_cast
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: "Digital Picture Frame",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.image_display
|
||||||
|
`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
heading: "Sonos Idle",
|
heading: "Sonos Idle",
|
||||||
config: `
|
config: `
|
||||||
@@ -48,11 +69,53 @@ const CONFIGS = [
|
|||||||
entity: media_player.sonos_idle
|
entity: media_player.sonos_idle
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: "Idle waiting for Browse Media",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.idle_browse_media
|
||||||
|
`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
heading: "Player Off",
|
heading: "Player Off",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.theater
|
entity: media_player.theater_off
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Player On",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.theater_on
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Player Off (cannot be switched on)",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.theater_off_static
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Player On (cannot be switched off)",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.theater_on_static
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Player Idle",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.idle
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Player Playing",
|
||||||
|
config: `
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.playing
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -70,14 +133,14 @@ const CONFIGS = [
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Receiver On",
|
heading: "Receiver On (selectable sources)",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.receiver_on
|
entity: media_player.receiver_on
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
heading: "Receiver Off",
|
heading: "Receiver Off (selectable sources)",
|
||||||
config: `
|
config: `
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.receiver_off
|
entity: media_player.receiver_off
|
||||||
|
|||||||
@@ -12,23 +12,45 @@ const CONFIGS = [
|
|||||||
- type: entities
|
- type: entities
|
||||||
entities:
|
entities:
|
||||||
- entity: media_player.music_paused
|
- entity: media_player.music_paused
|
||||||
name: Paused music
|
name: Paused Music
|
||||||
- entity: media_player.music_playing
|
- entity: media_player.music_playing
|
||||||
name: Playing music
|
name: Playing Music
|
||||||
- entity: media_player.stream_playing
|
- entity: media_player.stream_playing
|
||||||
name: Paused, no play
|
name: Playing Stream
|
||||||
- entity: media_player.living_room
|
- entity: media_player.stream_paused
|
||||||
name: Pause, No skip, tvshow
|
name: Paused Stream
|
||||||
|
- entity: media_player.stream_playing_previous
|
||||||
|
name: Playing Stream (with "previous" support)
|
||||||
|
- entity: media_player.tv_playing
|
||||||
|
name: Playing non-skip TV Show
|
||||||
- entity: media_player.android_cast
|
- entity: media_player.android_cast
|
||||||
name: Screen casting
|
name: Screen casting
|
||||||
|
- entity: media_player.image_display
|
||||||
|
name: Digital Picture Frame
|
||||||
- entity: media_player.sonos_idle
|
- entity: media_player.sonos_idle
|
||||||
name: Chromcast Idle
|
name: Sonos Idle
|
||||||
- entity: media_player.theater
|
- entity: media_player.idle_browse_media
|
||||||
|
name: Idle waiting for Browse Media
|
||||||
|
- entity: media_player.theater_off
|
||||||
name: Player Off
|
name: Player Off
|
||||||
|
- entity: media_player.theater_on
|
||||||
|
name: Player On
|
||||||
|
- entity: media_player.theater_off_static
|
||||||
|
name: Player Off (cannot be switched on)
|
||||||
|
- entity: media_player.theater_on_static
|
||||||
|
name: Player On (cannot be switched off)
|
||||||
|
- entity: media_player.idle
|
||||||
|
name: Player Idle
|
||||||
|
- entity: media_player.playing
|
||||||
|
name: Player Playing
|
||||||
- entity: media_player.unavailable
|
- entity: media_player.unavailable
|
||||||
name: Player Unavailable
|
name: Player Unavailable
|
||||||
- entity: media_player.unknown
|
- entity: media_player.unknown
|
||||||
name: Player Unknown
|
name: Player Unknown
|
||||||
|
- entity: media_player.receiver_on
|
||||||
|
name: Receiver On (selectable sources)
|
||||||
|
- entity: media_player.receiver_off
|
||||||
|
name: Receiver Off (selectable sources)
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
|
import { mockHistory } from "../../../demo/src/stubs/history";
|
||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-cards";
|
import "../components/demo-cards";
|
||||||
@@ -36,6 +37,10 @@ const ENTITIES = [
|
|||||||
battery: 71,
|
battery: 71,
|
||||||
friendly_name: "Home Boy",
|
friendly_name: "Home Boy",
|
||||||
}),
|
}),
|
||||||
|
getEntity("sensor", "illumination", "23", {
|
||||||
|
friendly_name: "Illumination",
|
||||||
|
unit_of_measurement: "lx",
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONFIGS = [
|
const CONFIGS = [
|
||||||
@@ -89,6 +94,42 @@ const CONFIGS = [
|
|||||||
entity: light.bed_light
|
entity: light.bed_light
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: "Default Grid",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_paulus
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.illumination
|
||||||
|
graph: line
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_anne_therese
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Non-square Grid with 2 columns",
|
||||||
|
config: `
|
||||||
|
- type: grid
|
||||||
|
columns: 2
|
||||||
|
square: false
|
||||||
|
cards:
|
||||||
|
- type: entity
|
||||||
|
entity: light.kitchen_lights
|
||||||
|
- type: entity
|
||||||
|
entity: light.bed_light
|
||||||
|
- type: entity
|
||||||
|
entity: device_tracker.demo_paulus
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.illumination
|
||||||
|
graph: line
|
||||||
|
`,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class DemoStack extends PolymerElement {
|
class DemoStack extends PolymerElement {
|
||||||
@@ -110,6 +151,7 @@ class DemoStack extends PolymerElement {
|
|||||||
const hass = provideHass(this.$.demos);
|
const hass = provideHass(this.$.demos);
|
||||||
hass.updateTranslations(null, "en");
|
hass.updateTranslations(null, "en");
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
|
mockHistory(hass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
|
|||||||
import { getEntity } from "../../../src/fake_data/entity";
|
import { getEntity } from "../../../src/fake_data/entity";
|
||||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||||
import "../components/demo-more-infos";
|
import "../components/demo-more-infos";
|
||||||
import "../components/more-info-content";
|
import "../../../src/dialogs/more-info/more-info-content";
|
||||||
|
|
||||||
const ENTITIES = [
|
const ENTITIES = [
|
||||||
getEntity("light", "bed_light", "on", {
|
getEntity("light", "bed_light", "on", {
|
||||||
@@ -40,8 +40,12 @@ class DemoMoreInfoLight extends PolymerElement {
|
|||||||
|
|
||||||
public ready() {
|
public ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
|
this._setupDemo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setupDemo() {
|
||||||
const hass = provideHass(this);
|
const hass = provideHass(this);
|
||||||
hass.updateTranslations(null, "en");
|
await hass.updateTranslations(null, "en");
|
||||||
hass.addEntities(ENTITIES);
|
hass.addEntities(ENTITIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ import { hassioStyle } from "../resources/hassio-style";
|
|||||||
class HassioAddonRepositoryEl extends LitElement {
|
class HassioAddonRepositoryEl extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public repo!: HassioAddonRepository;
|
@property({ attribute: false }) public repo!: HassioAddonRepository;
|
||||||
|
|
||||||
@property() public addons!: HassioAddonInfo[];
|
@property({ attribute: false }) public addons!: HassioAddonInfo[];
|
||||||
|
|
||||||
@property() public filter!: string;
|
@property() public filter!: string;
|
||||||
|
|
||||||
@@ -78,18 +78,18 @@ class HassioAddonRepositoryEl extends LitElement {
|
|||||||
.title=${addon.name}
|
.title=${addon.name}
|
||||||
.description=${addon.description}
|
.description=${addon.description}
|
||||||
.available=${addon.available}
|
.available=${addon.available}
|
||||||
.icon=${addon.installed && addon.installed !== addon.version
|
.icon=${addon.installed && addon.update_available
|
||||||
? mdiArrowUpBoldCircle
|
? mdiArrowUpBoldCircle
|
||||||
: mdiPuzzle}
|
: mdiPuzzle}
|
||||||
.iconTitle=${addon.installed
|
.iconTitle=${addon.installed
|
||||||
? addon.installed !== addon.version
|
? addon.update_available
|
||||||
? "New version available"
|
? "New version available"
|
||||||
: "Add-on is installed"
|
: "Add-on is installed"
|
||||||
: addon.available
|
: addon.available
|
||||||
? "Add-on is not installed"
|
? "Add-on is not installed"
|
||||||
: "Add-on is not available on your system"}
|
: "Add-on is not available on your system"}
|
||||||
.iconClass=${addon.installed
|
.iconClass=${addon.installed
|
||||||
? addon.installed !== addon.version
|
? addon.update_available
|
||||||
? "update"
|
? "update"
|
||||||
: "installed"
|
: "installed"
|
||||||
: !addon.available
|
: !addon.available
|
||||||
@@ -104,7 +104,7 @@ class HassioAddonRepositoryEl extends LitElement {
|
|||||||
: undefined}
|
: undefined}
|
||||||
.showTopbar=${addon.installed || !addon.available}
|
.showTopbar=${addon.installed || !addon.available}
|
||||||
.topbarClass=${addon.installed
|
.topbarClass=${addon.installed
|
||||||
? addon.installed !== addon.version
|
? addon.update_available
|
||||||
? "update"
|
? "update"
|
||||||
: "installed"
|
: "installed"
|
||||||
: !addon.available
|
: !addon.available
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { html, TemplateResult } from "lit-html";
|
import { html, TemplateResult } from "lit-html";
|
||||||
|
import { atLeastVersion } from "../../../src/common/config/version";
|
||||||
import "../../../src/common/search/search-input";
|
import "../../../src/common/search/search-input";
|
||||||
import "../../../src/components/ha-button-menu";
|
import "../../../src/components/ha-button-menu";
|
||||||
import "../../../src/components/ha-svg-icon";
|
import "../../../src/components/ha-svg-icon";
|
||||||
@@ -24,6 +25,7 @@ import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
|||||||
import "../../../src/layouts/hass-loading-screen";
|
import "../../../src/layouts/hass-loading-screen";
|
||||||
import "../../../src/layouts/hass-tabs-subpage";
|
import "../../../src/layouts/hass-tabs-subpage";
|
||||||
import { HomeAssistant, Route } from "../../../src/types";
|
import { HomeAssistant, Route } from "../../../src/types";
|
||||||
|
import { showRegistriesDialog } from "../dialogs/registries/show-dialog-registries";
|
||||||
import { showRepositoriesDialog } from "../dialogs/repositories/show-dialog-repositories";
|
import { showRepositoriesDialog } from "../dialogs/repositories/show-dialog-repositories";
|
||||||
import { supervisorTabs } from "../hassio-tabs";
|
import { supervisorTabs } from "../hassio-tabs";
|
||||||
import "./hassio-addon-repository";
|
import "./hassio-addon-repository";
|
||||||
@@ -98,14 +100,14 @@ class HassioAddonStore extends LitElement {
|
|||||||
main-page
|
main-page
|
||||||
.tabs=${supervisorTabs}
|
.tabs=${supervisorTabs}
|
||||||
>
|
>
|
||||||
<span slot="header">Add-on store</span>
|
<span slot="header">Add-on Store</span>
|
||||||
<ha-button-menu
|
<ha-button-menu
|
||||||
corner="BOTTOM_START"
|
corner="BOTTOM_START"
|
||||||
slot="toolbar-icon"
|
slot="toolbar-icon"
|
||||||
@action=${this._handleAction}
|
@action=${this._handleAction}
|
||||||
>
|
>
|
||||||
<mwc-icon-button slot="trigger" alt="menu">
|
<mwc-icon-button slot="trigger" alt="menu">
|
||||||
<ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
|
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
||||||
</mwc-icon-button>
|
</mwc-icon-button>
|
||||||
<mwc-list-item>
|
<mwc-list-item>
|
||||||
Repositories
|
Repositories
|
||||||
@@ -113,6 +115,12 @@ class HassioAddonStore extends LitElement {
|
|||||||
<mwc-list-item>
|
<mwc-list-item>
|
||||||
Reload
|
Reload
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
|
${this.hass.userData?.showAdvanced &&
|
||||||
|
atLeastVersion(this.hass.config.version, 0, 117)
|
||||||
|
? html`<mwc-list-item>
|
||||||
|
Registries
|
||||||
|
</mwc-list-item>`
|
||||||
|
: ""}
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
${repos.length === 0
|
${repos.length === 0
|
||||||
? html`<hass-loading-screen no-toolbar></hass-loading-screen>`
|
? html`<hass-loading-screen no-toolbar></hass-loading-screen>`
|
||||||
@@ -157,6 +165,9 @@ class HassioAddonStore extends LitElement {
|
|||||||
case 1:
|
case 1:
|
||||||
this.refreshData();
|
this.refreshData();
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
this._manageRegistries();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +184,10 @@ class HassioAddonStore extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _manageRegistries() {
|
||||||
|
showRegistriesDialog(this);
|
||||||
|
}
|
||||||
|
|
||||||
private async _loadData() {
|
private async _loadData() {
|
||||||
try {
|
try {
|
||||||
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
|
const addonsInfo = await fetchHassioAddonsInfo(this.hass);
|
||||||
|
|||||||