Compare commits
1 Commits
layout-str
...
hls-prefer
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6b2754c4cc |
@@ -1,13 +0,0 @@
|
|||||||
# 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"
|
|
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
"airbnb-typescript/base",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"airbnb-typescript/base",
|
||||||
"plugin:wc/recommended",
|
"plugin:wc/recommended",
|
||||||
"plugin:lit/recommended",
|
"plugin:lit/recommended",
|
||||||
"prettier",
|
"prettier",
|
||||||
@@ -45,16 +45,16 @@
|
|||||||
"func-names": 0,
|
"func-names": 0,
|
||||||
"prefer-arrow-callback": 0,
|
"prefer-arrow-callback": 0,
|
||||||
"no-underscore-dangle": 0,
|
"no-underscore-dangle": 0,
|
||||||
|
"no-var": 0,
|
||||||
"strict": 0,
|
"strict": 0,
|
||||||
"prefer-spread": 0,
|
"prefer-spread": 0,
|
||||||
"no-plusplus": 0,
|
"no-plusplus": 0,
|
||||||
"no-bitwise": 2,
|
"no-bitwise": 0,
|
||||||
"comma-dangle": 0,
|
"comma-dangle": 0,
|
||||||
"vars-on-top": 0,
|
"vars-on-top": 0,
|
||||||
"no-continue": 0,
|
"no-continue": 0,
|
||||||
"no-param-reassign": 0,
|
"no-param-reassign": 0,
|
||||||
"no-multi-assign": 0,
|
"no-multi-assign": 0,
|
||||||
"no-console": 2,
|
|
||||||
"radix": 0,
|
"radix": 0,
|
||||||
"no-alert": 0,
|
"no-alert": 0,
|
||||||
"no-return-await": 0,
|
"no-return-await": 0,
|
||||||
@@ -75,16 +75,13 @@
|
|||||||
"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-comment": 0,
|
"@typescript-eslint/ban-ts-ignore": 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"
|
||||||
|
2
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
@@ -51,7 +51,7 @@ DO NOT DELETE ANY TEXT from this template! Otherwise, your issue may be closed w
|
|||||||
<!--
|
<!--
|
||||||
Provide details about the versions you are using, which helps us reproducing
|
Provide details about the versions you are using, which helps us reproducing
|
||||||
and finding the issue quicker. Version information is found in the
|
and finding the issue quicker. Version information is found in the
|
||||||
Home Assistant frontend: Configuration -> Info.
|
Home Assistant frontend: Developer tools -> Info.
|
||||||
|
|
||||||
Browser version and operating system is important! Please try to replicate
|
Browser version and operating system is important! Please try to replicate
|
||||||
your issue in a different browser and be sure to include your findings.
|
your issue in a different browser and be sure to include your findings.
|
||||||
|
26
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
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,8 +1,5 @@
|
|||||||
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 or discussion
|
or resolves a feature request, be sure to link to that issue in the
|
||||||
in the additional information section.
|
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 or discussion:
|
- This PR is related to issue:
|
||||||
- Link to documentation pull request:
|
- Link to documentation pull request:
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
27
.github/lock.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# 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
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 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
|
6
.github/workflows/ci.yaml
vendored
@@ -34,8 +34,10 @@ jobs:
|
|||||||
run: yarn install
|
run: yarn install
|
||||||
env:
|
env:
|
||||||
CI: true
|
CI: true
|
||||||
- name: Build resources
|
- name: Build icons
|
||||||
run: ./node_modules/.bin/gulp gen-icons-json build-translations gather-gallery-demos
|
run: ./node_modules/.bin/gulp gen-icons-json
|
||||||
|
- name: Build translations
|
||||||
|
run: ./node_modules/.bin/gulp build-translations
|
||||||
- name: Run eslint
|
- name: Run eslint
|
||||||
run: ./node_modules/.bin/eslint '{**/src,src}/**/*.{js,ts,html}' --ignore-path .gitignore
|
run: ./node_modules/.bin/eslint '{**/src,src}/**/*.{js,ts,html}' --ignore-path .gitignore
|
||||||
- name: Run tsc
|
- name: Run tsc
|
||||||
|
60
.github/workflows/codeql-analysis.yml
vendored
@@ -1,60 +0,0 @@
|
|||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [dev, master]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [dev]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
# Override automatic language detection by changing the below list
|
|
||||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
|
||||||
language: ['javascript']
|
|
||||||
# Learn more...
|
|
||||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
# We must fetch at least the immediate parents so that if this is
|
|
||||||
# a pull request then we can checkout the head.
|
|
||||||
fetch-depth: 2
|
|
||||||
|
|
||||||
# If this run was triggered by a pull request event, then checkout
|
|
||||||
# the head of the pull request instead of the merge commit.
|
|
||||||
- run: git checkout HEAD^2
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v1
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v1
|
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
|
||||||
# 📚 https://git.io/JvXDl
|
|
||||||
|
|
||||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
|
||||||
# and modify them (or add more) to build your code if your project
|
|
||||||
# uses a compiled language
|
|
||||||
|
|
||||||
#- run: |
|
|
||||||
# make bootstrap
|
|
||||||
# make release
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v1
|
|
20
.github/workflows/lock.yml
vendored
@@ -1,20 +0,0 @@
|
|||||||
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
@@ -1,42 +0,0 @@
|
|||||||
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.
|
|
7
.gitignore
vendored
@@ -23,10 +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
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
@@ -35,6 +33,3 @@ yarn-error.log
|
|||||||
|
|
||||||
#asdf
|
#asdf
|
||||||
.tool-versions
|
.tool-versions
|
||||||
|
|
||||||
# Home Assistant config
|
|
||||||
/config
|
|
||||||
|
6
.hound.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
jshint:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
eslint:
|
||||||
|
enabled: true
|
||||||
|
config_file: .eslintrc-hound.json
|
44
.vscode/launch.json
vendored
@@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
// 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
@@ -1,208 +0,0 @@
|
|||||||
{
|
|
||||||
"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 variety of devices.
|
We use [BrowserStack](https://www.browserstack.com) to test Home Assistant on a large variation of devices.
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
# Bundling Home Assistant Frontend
|
|
||||||
|
|
||||||
The Home Assistant build pipeline contains various steps to prepare a build.
|
|
||||||
|
|
||||||
- Generating icon files to be included
|
|
||||||
- Generating translation files to be included
|
|
||||||
- Converting TypeScript, CSS and JSON files to JavaScript
|
|
||||||
- Bundling
|
|
||||||
- Minifying the files
|
|
||||||
- Generating the HTML entrypoint files
|
|
||||||
- Generating the service worker
|
|
||||||
- Compressing the files
|
|
||||||
|
|
||||||
## Converting files
|
|
||||||
|
|
||||||
Currently in Home Assistant we use a bundler to convert TypeScript, CSS and JSON files to JavaScript files that the browser understands.
|
|
||||||
|
|
||||||
We currently rely on Webpack but also have experimental Rollup support. Both of these programs bundle the converted files in both production and development.
|
|
||||||
|
|
||||||
For development, bundling is optional. We just want to get the right files in the browser.
|
|
||||||
|
|
||||||
Responsibilities of the converter during development:
|
|
||||||
|
|
||||||
- Convert TypeScript to JavaScript
|
|
||||||
- Convert CSS to JavaScript that sets the content as the default export
|
|
||||||
- Convert JSON to JavaScript that sets the content as the default export
|
|
||||||
- Make sure import, dynamic import and web worker references work
|
|
||||||
- Add extensions where missing
|
|
||||||
- Resolve absolute package imports
|
|
||||||
- Filter out specific imports/packages
|
|
||||||
- Replace constants with values
|
|
||||||
|
|
||||||
In production, the following responsibilities are added:
|
|
||||||
|
|
||||||
- Minify HTML
|
|
||||||
- Bundle multiple imports so that the browser can fetch less files
|
|
||||||
- Generate a second version that is ES5 compatible
|
|
||||||
|
|
||||||
Configuration for all these steps are specified in [bundle.js](bundle.js).
|
|
@@ -44,7 +44,7 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
module.exports.terserOptions = (latestBuild) => ({
|
module.exports.terserOptions = (latestBuild) => ({
|
||||||
safari10: !latestBuild,
|
safari10: true,
|
||||||
ecma: latestBuild ? undefined : 5,
|
ecma: latestBuild ? undefined : 5,
|
||||||
output: { comments: false },
|
output: { comments: false },
|
||||||
});
|
});
|
||||||
@@ -52,24 +52,17 @@ module.exports.terserOptions = (latestBuild) => ({
|
|||||||
module.exports.babelOptions = ({ latestBuild }) => ({
|
module.exports.babelOptions = ({ latestBuild }) => ({
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: [
|
||||||
!latestBuild && [
|
!latestBuild && [require("@babel/preset-env").default, { modules: false }],
|
||||||
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: [
|
||||||
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
||||||
!latestBuild && [
|
[
|
||||||
"@babel/plugin-proposal-object-rest-spread",
|
"@babel/plugin-proposal-object-rest-spread",
|
||||||
{ 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/plugin-syntax-import-meta",
|
"@babel/syntax-dynamic-import",
|
||||||
"@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",
|
||||||
[
|
[
|
||||||
@@ -80,7 +73,7 @@ module.exports.babelOptions = ({ latestBuild }) => ({
|
|||||||
require("@babel/plugin-proposal-class-properties").default,
|
require("@babel/plugin-proposal-class-properties").default,
|
||||||
{ loose: true },
|
{ loose: true },
|
||||||
],
|
],
|
||||||
].filter(Boolean),
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Are already ES5, cause warnings when babelified.
|
// Are already ES5, cause warnings when babelified.
|
||||||
@@ -117,7 +110,7 @@ BundleConfig {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports.config = {
|
module.exports.config = {
|
||||||
app({ isProdBuild, latestBuild, isStatsBuild, isWDS }) {
|
app({ isProdBuild, latestBuild, isStatsBuild }) {
|
||||||
return {
|
return {
|
||||||
entry: {
|
entry: {
|
||||||
service_worker: "./src/entrypoints/service_worker.ts",
|
service_worker: "./src/entrypoints/service_worker.ts",
|
||||||
@@ -132,7 +125,6 @@ module.exports.config = {
|
|||||||
isProdBuild,
|
isProdBuild,
|
||||||
latestBuild,
|
latestBuild,
|
||||||
isStatsBuild,
|
isStatsBuild,
|
||||||
isWDS,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -186,6 +178,7 @@ module.exports.config = {
|
|||||||
publicPath: publicPath(latestBuild, paths.hassio_publicPath),
|
publicPath: publicPath(latestBuild, paths.hassio_publicPath),
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
latestBuild,
|
latestBuild,
|
||||||
|
dontHash: new Set(["entrypoint"]),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@@ -6,9 +6,6 @@ module.exports = {
|
|||||||
useRollup() {
|
useRollup() {
|
||||||
return process.env.ROLLUP === "1";
|
return process.env.ROLLUP === "1";
|
||||||
},
|
},
|
||||||
useWDS() {
|
|
||||||
return process.env.WDS === "1";
|
|
||||||
},
|
|
||||||
isProdBuild() {
|
isProdBuild() {
|
||||||
return (
|
return (
|
||||||
process.env.NODE_ENV === "production" || module.exports.isStatsBuild()
|
process.env.NODE_ENV === "production" || module.exports.isStatsBuild()
|
||||||
|
@@ -12,7 +12,6 @@ require("./webpack.js");
|
|||||||
require("./service-worker.js");
|
require("./service-worker.js");
|
||||||
require("./entry-html.js");
|
require("./entry-html.js");
|
||||||
require("./rollup.js");
|
require("./rollup.js");
|
||||||
require("./wds.js");
|
|
||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"develop-app",
|
"develop-app",
|
||||||
@@ -29,11 +28,7 @@ gulp.task(
|
|||||||
"build-translations"
|
"build-translations"
|
||||||
),
|
),
|
||||||
"copy-static-app",
|
"copy-static-app",
|
||||||
env.useWDS()
|
env.useRollup() ? "rollup-watch-app" : "webpack-watch-app"
|
||||||
? "wds-watch-app"
|
|
||||||
: env.useRollup()
|
|
||||||
? "rollup-watch-app"
|
|
||||||
: "webpack-watch-app"
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -19,7 +19,6 @@ const renderTemplate = (pth, data = {}, pathFunc = templatePath) => {
|
|||||||
return compiled({
|
return compiled({
|
||||||
...data,
|
...data,
|
||||||
useRollup: env.useRollup(),
|
useRollup: env.useRollup(),
|
||||||
useWDS: env.useWDS(),
|
|
||||||
renderTemplate,
|
renderTemplate,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -91,23 +90,12 @@ gulp.task("gen-pages-prod", (done) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("gen-index-app-dev", (done) => {
|
gulp.task("gen-index-app-dev", (done) => {
|
||||||
let latestAppJS, latestCoreJS, latestCustomPanelJS;
|
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||||
|
// run webpack as last in watch mode, which blocks output.
|
||||||
if (env.useWDS()) {
|
|
||||||
latestAppJS = "http://localhost:8000/src/entrypoints/app.ts";
|
|
||||||
latestCoreJS = "http://localhost:8000/src/entrypoints/core.ts";
|
|
||||||
latestCustomPanelJS =
|
|
||||||
"http://localhost:8000/src/entrypoints/custom-panel.ts";
|
|
||||||
} else {
|
|
||||||
latestAppJS = "/frontend_latest/app.js";
|
|
||||||
latestCoreJS = "/frontend_latest/core.js";
|
|
||||||
latestCustomPanelJS = "/frontend_latest/custom-panel.js";
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = renderTemplate("index", {
|
const content = renderTemplate("index", {
|
||||||
latestAppJS,
|
latestAppJS: "/frontend_latest/app.js",
|
||||||
latestCoreJS,
|
latestCoreJS: "/frontend_latest/core.js",
|
||||||
latestCustomPanelJS,
|
latestCustomPanelJS: "/frontend_latest/custom-panel.js",
|
||||||
|
|
||||||
es5AppJS: "/frontend_es5/app.js",
|
es5AppJS: "/frontend_es5/app.js",
|
||||||
es5CoreJS: "/frontend_es5/core.js",
|
es5CoreJS: "/frontend_es5/core.js",
|
||||||
@@ -213,6 +201,8 @@ gulp.task("gen-index-cast-prod", (done) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("gen-index-demo-dev", (done) => {
|
gulp.task("gen-index-demo-dev", (done) => {
|
||||||
|
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||||
|
// run webpack as last in watch mode, which blocks output.
|
||||||
const content = renderDemoTemplate("index", {
|
const content = renderDemoTemplate("index", {
|
||||||
latestDemoJS: "/frontend_latest/main.js",
|
latestDemoJS: "/frontend_latest/main.js",
|
||||||
|
|
||||||
@@ -250,6 +240,8 @@ gulp.task("gen-index-demo-prod", (done) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("gen-index-gallery-dev", (done) => {
|
gulp.task("gen-index-gallery-dev", (done) => {
|
||||||
|
// In dev mode we don't mangle names, so we hardcode urls. That way we can
|
||||||
|
// run webpack as last in watch mode, which blocks output.
|
||||||
const content = renderGalleryTemplate("index", {
|
const content = renderGalleryTemplate("index", {
|
||||||
latestGalleryJS: "./frontend_latest/entrypoint.js",
|
latestGalleryJS: "./frontend_latest/entrypoint.js",
|
||||||
});
|
});
|
||||||
@@ -277,42 +269,3 @@ gulp.task("gen-index-gallery-prod", (done) => {
|
|||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("gen-index-hassio-dev", async () => {
|
|
||||||
writeHassioEntrypoint(
|
|
||||||
`${paths.hassio_publicPath}/frontend_latest/entrypoint.js`,
|
|
||||||
`${paths.hassio_publicPath}/frontend_es5/entrypoint.js`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("gen-index-hassio-prod", async () => {
|
|
||||||
const latestManifest = require(path.resolve(
|
|
||||||
paths.hassio_output_latest,
|
|
||||||
"manifest.json"
|
|
||||||
));
|
|
||||||
const es5Manifest = require(path.resolve(
|
|
||||||
paths.hassio_output_es5,
|
|
||||||
"manifest.json"
|
|
||||||
));
|
|
||||||
writeHassioEntrypoint(
|
|
||||||
latestManifest["entrypoint.js"],
|
|
||||||
es5Manifest["entrypoint.js"]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function writeHassioEntrypoint(latestEntrypoint, es5Entrypoint) {
|
|
||||||
fs.mkdirSync(paths.hassio_output_root, { recursive: true });
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.resolve(paths.hassio_output_root, "entrypoint.js"),
|
|
||||||
`
|
|
||||||
try {
|
|
||||||
new Function("import('${latestEntrypoint}')")();
|
|
||||||
} catch (err) {
|
|
||||||
var el = document.createElement('script');
|
|
||||||
el.src = '${es5Entrypoint}';
|
|
||||||
document.body.appendChild(el);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
{ encoding: "utf-8" }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
// Run demo develop mode
|
// Run demo develop mode
|
||||||
const gulp = require("gulp");
|
const gulp = require("gulp");
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
const env = require("../env");
|
const env = require("../env");
|
||||||
const paths = require("../paths");
|
|
||||||
|
|
||||||
require("./clean.js");
|
require("./clean.js");
|
||||||
require("./translations.js");
|
require("./translations.js");
|
||||||
@@ -15,31 +12,6 @@ require("./service-worker.js");
|
|||||||
require("./entry-html.js");
|
require("./entry-html.js");
|
||||||
require("./rollup.js");
|
require("./rollup.js");
|
||||||
|
|
||||||
gulp.task("gather-gallery-demos", async function gatherDemos() {
|
|
||||||
const files = await fs.promises.readdir(
|
|
||||||
path.resolve(paths.gallery_dir, "src/demos")
|
|
||||||
);
|
|
||||||
|
|
||||||
let content = "export const DEMOS = {\n";
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const demoId = path.basename(file, ".ts");
|
|
||||||
const demoPath = "../src/demos/" + demoId;
|
|
||||||
content += ` "${demoId}": () => import("${demoPath}"),\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
content += "};";
|
|
||||||
|
|
||||||
const galleryBuild = path.resolve(paths.gallery_dir, "build");
|
|
||||||
|
|
||||||
fs.mkdirSync(galleryBuild, { recursive: true });
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.resolve(galleryBuild, "import-demos.ts"),
|
|
||||||
content,
|
|
||||||
"utf-8"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"develop-gallery",
|
"develop-gallery",
|
||||||
gulp.series(
|
gulp.series(
|
||||||
@@ -48,11 +20,7 @@ gulp.task(
|
|||||||
},
|
},
|
||||||
"clean-gallery",
|
"clean-gallery",
|
||||||
"translations-enable-merge-backend",
|
"translations-enable-merge-backend",
|
||||||
gulp.parallel(
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"gen-icons-json",
|
|
||||||
"build-translations",
|
|
||||||
"gather-gallery-demos"
|
|
||||||
),
|
|
||||||
"copy-static-gallery",
|
"copy-static-gallery",
|
||||||
"gen-index-gallery-dev",
|
"gen-index-gallery-dev",
|
||||||
env.useRollup() ? "rollup-dev-server-gallery" : "webpack-dev-server-gallery"
|
env.useRollup() ? "rollup-dev-server-gallery" : "webpack-dev-server-gallery"
|
||||||
@@ -67,11 +35,7 @@ gulp.task(
|
|||||||
},
|
},
|
||||||
"clean-gallery",
|
"clean-gallery",
|
||||||
"translations-enable-merge-backend",
|
"translations-enable-merge-backend",
|
||||||
gulp.parallel(
|
gulp.parallel("gen-icons-json", "build-translations"),
|
||||||
"gen-icons-json",
|
|
||||||
"build-translations",
|
|
||||||
"gather-gallery-demos"
|
|
||||||
),
|
|
||||||
"copy-static-gallery",
|
"copy-static-gallery",
|
||||||
env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery",
|
env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery",
|
||||||
"gen-index-gallery-prod"
|
"gen-index-gallery-prod"
|
||||||
|
@@ -11,7 +11,6 @@ const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json");
|
|||||||
const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json");
|
const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json");
|
||||||
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
|
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
|
||||||
const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi");
|
const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi");
|
||||||
const REMOVED_ICONS_PATH = path.resolve(__dirname, "../removedIcons.json");
|
|
||||||
|
|
||||||
const encoding = "utf8";
|
const encoding = "utf8";
|
||||||
|
|
||||||
@@ -26,13 +25,6 @@ const getMeta = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const addRemovedMeta = (meta) => {
|
|
||||||
const file = fs.readFileSync(REMOVED_ICONS_PATH, { encoding });
|
|
||||||
const removed = JSON.parse(file);
|
|
||||||
const combinedMeta = [...meta, ...removed];
|
|
||||||
return combinedMeta.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
};
|
|
||||||
|
|
||||||
const splitBySize = (meta) => {
|
const splitBySize = (meta) => {
|
||||||
const chunks = [];
|
const chunks = [];
|
||||||
const CHUNK_SIZE = 50000;
|
const CHUNK_SIZE = 50000;
|
||||||
@@ -77,7 +69,7 @@ const findDifferentiator = (curString, prevString) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
gulp.task("gen-icons-json", (done) => {
|
gulp.task("gen-icons-json", (done) => {
|
||||||
const meta = addRemovedMeta(getMeta());
|
const meta = getMeta();
|
||||||
const split = splitBySize(meta);
|
const split = splitBySize(meta);
|
||||||
|
|
||||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
if (!fs.existsSync(OUTPUT_DIR)) {
|
||||||
|
@@ -11,6 +11,24 @@ require("./webpack.js");
|
|||||||
require("./compress.js");
|
require("./compress.js");
|
||||||
require("./rollup.js");
|
require("./rollup.js");
|
||||||
|
|
||||||
|
async function writeEntrypointJS() {
|
||||||
|
// We ship two builds and we need to do feature detection on what version to load.
|
||||||
|
fs.mkdirSync(paths.hassio_output_root, { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.resolve(paths.hassio_output_root, "entrypoint.js"),
|
||||||
|
`
|
||||||
|
try {
|
||||||
|
new Function("import('${paths.hassio_publicPath}/frontend_latest/entrypoint.js')")();
|
||||||
|
} catch (err) {
|
||||||
|
var el = document.createElement('script');
|
||||||
|
el.src = '${paths.hassio_publicPath}/frontend_es5/entrypoint.js';
|
||||||
|
document.body.appendChild(el);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{ encoding: "utf-8" }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"develop-hassio",
|
"develop-hassio",
|
||||||
gulp.series(
|
gulp.series(
|
||||||
@@ -19,7 +37,7 @@ gulp.task(
|
|||||||
},
|
},
|
||||||
"clean-hassio",
|
"clean-hassio",
|
||||||
"gen-icons-json",
|
"gen-icons-json",
|
||||||
"gen-index-hassio-dev",
|
writeEntrypointJS,
|
||||||
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
|
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -33,7 +51,7 @@ gulp.task(
|
|||||||
"clean-hassio",
|
"clean-hassio",
|
||||||
"gen-icons-json",
|
"gen-icons-json",
|
||||||
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
|
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
|
||||||
"gen-index-hassio-prod",
|
writeEntrypointJS,
|
||||||
...// Don't compress running tests
|
...// Don't compress running tests
|
||||||
(env.isTest() ? [] : ["compress-hassio"])
|
(env.isTest() ? [] : ["compress-hassio"])
|
||||||
)
|
)
|
||||||
|
@@ -7,6 +7,7 @@ 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");
|
||||||
@@ -33,10 +34,21 @@ String.prototype.rsplit = function (sep, maxsplit) {
|
|||||||
: split;
|
: split;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Panel translations which should be split from the core translations.
|
// Panel translations which should be split from the core translations. These
|
||||||
const TRANSLATION_FRAGMENTS = Object.keys(
|
// should mirror the fragment definitions in polymer.json, so that we load
|
||||||
require("../../src/translations/en.json").ui.panel
|
// additional resources at equivalent points.
|
||||||
);
|
const TRANSLATION_FRAGMENTS = [
|
||||||
|
"config",
|
||||||
|
"history",
|
||||||
|
"logbook",
|
||||||
|
"mailbox",
|
||||||
|
"profile",
|
||||||
|
"shopping-list",
|
||||||
|
"page-authorize",
|
||||||
|
"page-demo",
|
||||||
|
"page-onboarding",
|
||||||
|
"developer-tools",
|
||||||
|
];
|
||||||
|
|
||||||
function recursiveFlatten(prefix, data) {
|
function recursiveFlatten(prefix, data) {
|
||||||
let output = {};
|
let output = {};
|
||||||
@@ -289,6 +301,7 @@ 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") {
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
// Tasks to run Rollup
|
|
||||||
const gulp = require("gulp");
|
|
||||||
const { startDevServer } = require("@web/dev-server");
|
|
||||||
|
|
||||||
gulp.task("wds-watch-app", () => {
|
|
||||||
startDevServer({
|
|
||||||
config: {
|
|
||||||
watch: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
@@ -18,14 +18,6 @@ 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,
|
||||||
@@ -41,13 +33,10 @@ const runDevServer = ({
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
// Server listening
|
// Server listening
|
||||||
log(
|
log("[webpack-dev-server]", `http://localhost:${port}`);
|
||||||
"[webpack-dev-server]",
|
|
||||||
`Project is running at http://localhost:${port}`
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const doneHandler = (done) => (err, stats) => {
|
const handler = (done) => (err, stats) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
log.error(err.stack || err);
|
log.error(err.stack || err);
|
||||||
if (err.details) {
|
if (err.details) {
|
||||||
@@ -56,31 +45,22 @@ const doneHandler = (done) => (err, stats) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats.hasErrors() || stats.hasWarnings()) {
|
|
||||||
console.log(stats.toString("minimal"));
|
|
||||||
}
|
|
||||||
|
|
||||||
log(`Build done @ ${new Date().toLocaleTimeString()}`);
|
log(`Build done @ ${new Date().toLocaleTimeString()}`);
|
||||||
|
|
||||||
|
if (stats.hasErrors() || stats.hasWarnings()) {
|
||||||
|
log.warn(stats.toString("minimal"));
|
||||||
|
}
|
||||||
|
|
||||||
if (done) {
|
if (done) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const prodBuild = (conf) =>
|
|
||||||
new Promise((resolve) => {
|
|
||||||
webpack(
|
|
||||||
conf,
|
|
||||||
// Resolve promise when done. Because we pass a callback, webpack closes itself
|
|
||||||
doneHandler(resolve)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("webpack-watch-app", () => {
|
gulp.task("webpack-watch-app", () => {
|
||||||
// This command will run forever because we don't close compiler
|
// we are not calling done, so this command will run forever
|
||||||
webpack(createAppConfig({ isProdBuild: false, latestBuild: true })).watch(
|
webpack(createAppConfig({ isProdBuild: false, latestBuild: true })).watch(
|
||||||
{ ignored: /build-translations/ },
|
{ ignored: /build-translations/ },
|
||||||
doneHandler()
|
handler()
|
||||||
);
|
);
|
||||||
gulp.watch(
|
gulp.watch(
|
||||||
path.join(paths.translations_src, "en.json"),
|
path.join(paths.translations_src, "en.json"),
|
||||||
@@ -88,12 +68,15 @@ gulp.task("webpack-watch-app", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("webpack-prod-app", () =>
|
gulp.task(
|
||||||
prodBuild(
|
"webpack-prod-app",
|
||||||
bothBuilds(createAppConfig, {
|
() =>
|
||||||
isProdBuild: true,
|
new Promise((resolve) =>
|
||||||
})
|
webpack(
|
||||||
)
|
bothBuilds(createAppConfig, { isProdBuild: true }),
|
||||||
|
handler(resolve)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task("webpack-dev-server-demo", () => {
|
gulp.task("webpack-dev-server-demo", () => {
|
||||||
@@ -104,12 +87,17 @@ gulp.task("webpack-dev-server-demo", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("webpack-prod-demo", () =>
|
gulp.task(
|
||||||
prodBuild(
|
"webpack-prod-demo",
|
||||||
bothBuilds(createDemoConfig, {
|
() =>
|
||||||
isProdBuild: true,
|
new Promise((resolve) =>
|
||||||
})
|
webpack(
|
||||||
)
|
bothBuilds(createDemoConfig, {
|
||||||
|
isProdBuild: true,
|
||||||
|
}),
|
||||||
|
handler(resolve)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task("webpack-dev-server-cast", () => {
|
gulp.task("webpack-dev-server-cast", () => {
|
||||||
@@ -122,30 +110,41 @@ gulp.task("webpack-dev-server-cast", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("webpack-prod-cast", () =>
|
gulp.task(
|
||||||
prodBuild(
|
"webpack-prod-cast",
|
||||||
bothBuilds(createCastConfig, {
|
() =>
|
||||||
isProdBuild: true,
|
new Promise((resolve) =>
|
||||||
})
|
webpack(
|
||||||
)
|
bothBuilds(createCastConfig, {
|
||||||
|
isProdBuild: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
handler(resolve)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task("webpack-watch-hassio", () => {
|
gulp.task("webpack-watch-hassio", () => {
|
||||||
// This command will run forever because we don't close compiler
|
// we are not calling done, so this command will run forever
|
||||||
webpack(
|
webpack(
|
||||||
createHassioConfig({
|
createHassioConfig({
|
||||||
isProdBuild: false,
|
isProdBuild: false,
|
||||||
latestBuild: true,
|
latestBuild: true,
|
||||||
})
|
})
|
||||||
).watch({}, doneHandler());
|
).watch({}, handler());
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("webpack-prod-hassio", () =>
|
gulp.task(
|
||||||
prodBuild(
|
"webpack-prod-hassio",
|
||||||
bothBuilds(createHassioConfig, {
|
() =>
|
||||||
isProdBuild: true,
|
new Promise((resolve) =>
|
||||||
})
|
webpack(
|
||||||
)
|
bothBuilds(createHassioConfig, {
|
||||||
|
isProdBuild: true,
|
||||||
|
}),
|
||||||
|
handler(resolve)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task("webpack-dev-server-gallery", () => {
|
gulp.task("webpack-dev-server-gallery", () => {
|
||||||
@@ -157,11 +156,17 @@ gulp.task("webpack-dev-server-gallery", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("webpack-prod-gallery", () =>
|
gulp.task(
|
||||||
prodBuild(
|
"webpack-prod-gallery",
|
||||||
createGalleryConfig({
|
() =>
|
||||||
isProdBuild: true,
|
new Promise((resolve) =>
|
||||||
latestBuild: true,
|
webpack(
|
||||||
})
|
createGalleryConfig({
|
||||||
)
|
isProdBuild: true,
|
||||||
|
latestBuild: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
handler(resolve)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
const path = require("path");
|
var path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
polymer_dir: path.resolve(__dirname, ".."),
|
polymer_dir: path.resolve(__dirname, ".."),
|
||||||
@@ -34,11 +34,6 @@ module.exports = {
|
|||||||
|
|
||||||
hassio_dir: path.resolve(__dirname, "../hassio"),
|
hassio_dir: path.resolve(__dirname, "../hassio"),
|
||||||
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
|
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
|
||||||
hassio_output_latest: path.resolve(
|
|
||||||
__dirname,
|
|
||||||
"../hassio/build/frontend_latest"
|
|
||||||
),
|
|
||||||
hassio_output_es5: path.resolve(__dirname, "../hassio/build/frontend_es5"),
|
|
||||||
hassio_publicPath: "/api/hassio/app",
|
hassio_publicPath: "/api/hassio/app",
|
||||||
|
|
||||||
translations_src: path.resolve(__dirname, "../src/translations"),
|
translations_src: path.resolve(__dirname, "../src/translations"),
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
[]
|
|
@@ -1,3 +1,5 @@
|
|||||||
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = function (userOptions = {}) {
|
module.exports = function (userOptions = {}) {
|
||||||
// Files need to be absolute paths.
|
// Files need to be absolute paths.
|
||||||
// This only works if the file has no exports
|
// This only works if the file has no exports
|
||||||
|
@@ -3,7 +3,7 @@ const path = require("path");
|
|||||||
const commonjs = require("@rollup/plugin-commonjs");
|
const commonjs = require("@rollup/plugin-commonjs");
|
||||||
const resolve = require("@rollup/plugin-node-resolve");
|
const resolve = require("@rollup/plugin-node-resolve");
|
||||||
const json = require("@rollup/plugin-json");
|
const json = require("@rollup/plugin-json");
|
||||||
const babel = require("@rollup/plugin-babel").babel;
|
const babel = require("rollup-plugin-babel");
|
||||||
const replace = require("@rollup/plugin-replace");
|
const replace = require("@rollup/plugin-replace");
|
||||||
const visualizer = require("rollup-plugin-visualizer");
|
const visualizer = require("rollup-plugin-visualizer");
|
||||||
const { string } = require("rollup-plugin-string");
|
const { string } = require("rollup-plugin-string");
|
||||||
@@ -31,7 +31,6 @@ const createRollupConfig = ({
|
|||||||
isStatsBuild,
|
isStatsBuild,
|
||||||
publicPath,
|
publicPath,
|
||||||
dontHash,
|
dontHash,
|
||||||
isWDS,
|
|
||||||
}) => {
|
}) => {
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +61,6 @@ const createRollupConfig = ({
|
|||||||
...bundle.babelOptions({ latestBuild }),
|
...bundle.babelOptions({ latestBuild }),
|
||||||
extensions,
|
extensions,
|
||||||
exclude: bundle.babelExclude(),
|
exclude: bundle.babelExclude(),
|
||||||
babelHelpers: isWDS ? "inline" : "bundled",
|
|
||||||
}),
|
}),
|
||||||
string({
|
string({
|
||||||
// Import certain extensions as strings
|
// Import certain extensions as strings
|
||||||
@@ -71,21 +69,19 @@ const createRollupConfig = ({
|
|||||||
replace(
|
replace(
|
||||||
bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })
|
bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })
|
||||||
),
|
),
|
||||||
!isWDS &&
|
manifest({
|
||||||
manifest({
|
publicPath,
|
||||||
publicPath,
|
}),
|
||||||
}),
|
worker(),
|
||||||
!isWDS && worker(),
|
dontHashPlugin({ dontHash }),
|
||||||
!isWDS && dontHashPlugin({ dontHash }),
|
isProdBuild && terser(bundle.terserOptions(latestBuild)),
|
||||||
!isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)),
|
isStatsBuild &&
|
||||||
!isWDS &&
|
|
||||||
isStatsBuild &&
|
|
||||||
visualizer({
|
visualizer({
|
||||||
// https://github.com/btd/rollup-plugin-visualizer#options
|
// https://github.com/btd/rollup-plugin-visualizer#options
|
||||||
open: true,
|
open: true,
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
}),
|
}),
|
||||||
].filter(Boolean),
|
],
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @type { import("rollup").OutputOptions }
|
* @type { import("rollup").OutputOptions }
|
||||||
@@ -112,13 +108,12 @@ const createRollupConfig = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) => {
|
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
||||||
return createRollupConfig(
|
return createRollupConfig(
|
||||||
bundle.config.app({
|
bundle.config.app({
|
||||||
isProdBuild,
|
isProdBuild,
|
||||||
latestBuild,
|
latestBuild,
|
||||||
isStatsBuild,
|
isStatsBuild,
|
||||||
isWDS,
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -2,23 +2,9 @@ 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,
|
||||||
@@ -44,7 +30,7 @@ const createWebpackConfig = ({
|
|||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.m?js$|\.ts$/,
|
test: /\.js$|\.ts$/,
|
||||||
exclude: bundle.babelExclude(),
|
exclude: bundle.babelExclude(),
|
||||||
use: {
|
use: {
|
||||||
loader: "babel-loader",
|
loader: "babel-loader",
|
||||||
@@ -60,13 +46,16 @@ 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"),
|
||||||
@@ -110,17 +99,7 @@ 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"],
|
||||||
},
|
},
|
||||||
@@ -131,22 +110,6 @@ 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: 16 KiB After Width: | Height: | Size: 18 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 |
@@ -37,21 +37,23 @@
|
|||||||
<body>
|
<body>
|
||||||
<%= renderTemplate('_js_base') %>
|
<%= renderTemplate('_js_base') %>
|
||||||
|
|
||||||
<script>
|
<script type="module" crossorigin="use-credentials">
|
||||||
import("<%= latestLauncherJS %>");
|
import "<%= latestLauncherJS %>";
|
||||||
window.latestJS = true;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script nomodule>
|
||||||
if (!window.latestJS) {
|
(function() {
|
||||||
<% if (useRollup) { %>
|
// // Safari 10.1 supports type=module but ignores nomodule, so we add this check.
|
||||||
_ls("/static/js/s.min.js").onload = function() {
|
if (!isS101) {
|
||||||
System.import("<%= es5LauncherJS %>");
|
<% if (useRollup) { %>
|
||||||
};
|
_ls("/static/js/s.min.js").onload = function() {
|
||||||
<% } else { %>
|
System.import("<%= es5LauncherJS %>");
|
||||||
_ls("<%= es5LauncherJS %>");
|
};
|
||||||
<% } %>
|
<% } else { %>
|
||||||
}
|
_ls("<%= es5LauncherJS %>");
|
||||||
|
<% } %>
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<hc-layout subtitle="FAQ">
|
<hc-layout subtitle="FAQ">
|
||||||
@@ -212,8 +214,13 @@
|
|||||||
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 iOS)</li>
|
<li>Google Chrome (all platforms except on iOS)</li>
|
||||||
<li>Microsoft Edge (all platforms)</li>
|
<li>
|
||||||
|
Microsoft Edge (all platforms,
|
||||||
|
<a href="https://www.microsoftedgeinsider.com" target="_blank"
|
||||||
|
>dev and canary builds only</a
|
||||||
|
>)
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -246,7 +253,7 @@ http:
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
var _gaq = [["_setAccount", "UA-57927901-9"], ["_trackPageview"]];
|
var _gaq = [["_setAccount", "UA-57927901-9"], ["_trackPageview"]];
|
||||||
(function (d, t) {
|
(function(d, t) {
|
||||||
var g = d.createElement(t),
|
var g = d.createElement(t),
|
||||||
s = d.getElementsByTagName(t)[0];
|
s = d.getElementsByTagName(t)[0];
|
||||||
g.src =
|
g.src =
|
||||||
|
@@ -28,21 +28,23 @@
|
|||||||
|
|
||||||
<hc-connect></hc-connect>
|
<hc-connect></hc-connect>
|
||||||
|
|
||||||
<script>
|
<script type="module" crossorigin="use-credentials">
|
||||||
import("<%= latestLauncherJS %>");
|
import "<%= latestLauncherJS %>";
|
||||||
window.latestJS = true;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script nomodule>
|
||||||
if (!window.latestJS) {
|
(function() {
|
||||||
<% if (useRollup) { %>
|
// // Safari 10.1 supports type=module but ignores nomodule, so we add this check.
|
||||||
_ls("/static/js/s.min.js").onload = function() {
|
if (!isS101) {
|
||||||
System.import("<%= es5LauncherJS %>");
|
<% if (useRollup) { %>
|
||||||
};
|
_ls("/static/js/s.min.js").onload = function() {
|
||||||
<% } else { %>
|
System.import("<%= es5LauncherJS %>");
|
||||||
_ls("<%= es5LauncherJS %>");
|
};
|
||||||
<% } %>
|
<% } else { %>
|
||||||
}
|
_ls("<%= es5LauncherJS %>");
|
||||||
|
<% } %>
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import "../../../src/resources/safari-14-attachshadow-patch";
|
|
||||||
import "../../../src/resources/ha-style";
|
import "../../../src/resources/ha-style";
|
||||||
import "../../../src/resources/roboto";
|
import "../../../src/resources/roboto";
|
||||||
import "./layout/hc-connect";
|
import "./layout/hc-connect";
|
||||||
|
@@ -8,7 +8,6 @@ import {
|
|||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { CastManager } from "../../../../src/cast/cast_manager";
|
import { CastManager } from "../../../../src/cast/cast_manager";
|
||||||
@@ -29,7 +28,7 @@ import {
|
|||||||
getLovelaceCollection,
|
getLovelaceCollection,
|
||||||
LovelaceConfig,
|
LovelaceConfig,
|
||||||
} from "../../../../src/data/lovelace";
|
} from "../../../../src/data/lovelace";
|
||||||
import "../../../../src/layouts/hass-loading-screen";
|
import "../../../../src/layouts/loading-screen";
|
||||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
||||||
import "./hc-layout";
|
import "./hc-layout";
|
||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
@@ -42,13 +41,13 @@ class HcCast extends LitElement {
|
|||||||
|
|
||||||
@property() public castManager!: CastManager;
|
@property() public castManager!: CastManager;
|
||||||
|
|
||||||
@internalProperty() private askWrite = false;
|
@property() private askWrite = false;
|
||||||
|
|
||||||
@internalProperty() private lovelaceConfig?: LovelaceConfig | null;
|
@property() private lovelaceConfig?: LovelaceConfig | null;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this.lovelaceConfig === undefined) {
|
if (this.lovelaceConfig === undefined) {
|
||||||
return html` <hass-loading-screen no-toolbar></hass-loading-screen>> `;
|
return html` <loading-screen></loading-screen>> `;
|
||||||
}
|
}
|
||||||
|
|
||||||
const error =
|
const error =
|
||||||
|
@@ -17,8 +17,8 @@ import {
|
|||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
|
property,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
internalProperty,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
||||||
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
||||||
@@ -27,7 +27,7 @@ import {
|
|||||||
saveTokens,
|
saveTokens,
|
||||||
} from "../../../../src/common/auth/token_storage";
|
} from "../../../../src/common/auth/token_storage";
|
||||||
import "../../../../src/components/ha-icon";
|
import "../../../../src/components/ha-icon";
|
||||||
import "../../../../src/layouts/hass-loading-screen";
|
import "../../../../src/layouts/loading-screen";
|
||||||
import { registerServiceWorker } from "../../../../src/util/register-service-worker";
|
import { registerServiceWorker } from "../../../../src/util/register-service-worker";
|
||||||
import "./hc-layout";
|
import "./hc-layout";
|
||||||
|
|
||||||
@@ -60,19 +60,19 @@ const INTRO = html`
|
|||||||
|
|
||||||
@customElement("hc-connect")
|
@customElement("hc-connect")
|
||||||
export class HcConnect extends LitElement {
|
export class HcConnect extends LitElement {
|
||||||
@internalProperty() private loading = false;
|
@property() private loading = false;
|
||||||
|
|
||||||
// If we had stored credentials but we cannot connect,
|
// If we had stored credentials but we cannot connect,
|
||||||
// show a screen asking retry or logout.
|
// show a screen asking retry or logout.
|
||||||
@internalProperty() private cannotConnect = false;
|
@property() private cannotConnect = false;
|
||||||
|
|
||||||
@internalProperty() private error?: string | TemplateResult;
|
@property() private error?: string | TemplateResult;
|
||||||
|
|
||||||
@internalProperty() private auth?: Auth;
|
@property() private auth?: Auth;
|
||||||
|
|
||||||
@internalProperty() private connection?: Connection;
|
@property() private connection?: Connection;
|
||||||
|
|
||||||
@internalProperty() private castManager?: CastManager | null;
|
@property() private castManager?: CastManager | null;
|
||||||
|
|
||||||
private openDemo = false;
|
private openDemo = false;
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ export class HcConnect extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.castManager === undefined || this.loading) {
|
if (this.castManager === undefined || this.loading) {
|
||||||
return html` <hass-loading-screen no-toolbar></hass-loading-screen> `;
|
return html` <loading-screen></loading-screen> `;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.castManager === null) {
|
if (this.castManager === null) {
|
||||||
|
@@ -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" />
|
||||||
<h1 class="card-header">
|
<div 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>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</h1>
|
</div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
@@ -6,60 +6,13 @@ 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 lovelaceController = new HcMain();
|
const controller = new HcMain();
|
||||||
document.body.append(lovelaceController);
|
document.body.append(controller);
|
||||||
|
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,61 +30,13 @@ 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;
|
||||||
lovelaceController.processIncomingMessage(msg);
|
controller.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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -1,10 +1,4 @@
|
|||||||
import {
|
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
property,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { mockHistory } from "../../../../demo/src/stubs/history";
|
import { mockHistory } from "../../../../demo/src/stubs/history";
|
||||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||||
import {
|
import {
|
||||||
@@ -19,9 +13,9 @@ import "./hc-lovelace";
|
|||||||
|
|
||||||
@customElement("hc-demo")
|
@customElement("hc-demo")
|
||||||
class HcDemo extends HassElement {
|
class HcDemo extends HassElement {
|
||||||
@property({ attribute: false }) public lovelacePath!: string;
|
@property() public lovelacePath!: string;
|
||||||
|
|
||||||
@internalProperty() private _lovelaceConfig?: LovelaceConfig;
|
@property() private _lovelaceConfig?: LovelaceConfig;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this._lovelaceConfig) {
|
if (!this._lovelaceConfig) {
|
||||||
|
@@ -11,7 +11,7 @@ import { HomeAssistant } from "../../../../src/types";
|
|||||||
|
|
||||||
@customElement("hc-launch-screen")
|
@customElement("hc-launch-screen")
|
||||||
class HcLaunchScreen extends LitElement {
|
class HcLaunchScreen extends LitElement {
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property() public error?: string;
|
@property() public error?: string;
|
||||||
|
|
||||||
|
@@ -9,20 +9,19 @@ 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";
|
||||||
|
|
||||||
@customElement("hc-lovelace")
|
@customElement("hc-lovelace")
|
||||||
class HcLovelace extends LitElement {
|
class HcLovelace extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public lovelaceConfig!: LovelaceConfig;
|
@property() public lovelaceConfig!: LovelaceConfig;
|
||||||
|
|
||||||
@property() public viewPath?: string | number;
|
@property() public viewPath?: string | number;
|
||||||
|
|
||||||
public urlPath?: string | null;
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const index = this._viewIndex;
|
const index = this._viewIndex;
|
||||||
if (index === undefined) {
|
if (index === undefined) {
|
||||||
@@ -36,7 +35,6 @@ class HcLovelace extends LitElement {
|
|||||||
const lovelace: Lovelace = {
|
const lovelace: Lovelace = {
|
||||||
config: this.lovelaceConfig,
|
config: this.lovelaceConfig,
|
||||||
editMode: false,
|
editMode: false,
|
||||||
urlPath: this.urlPath!,
|
|
||||||
enableFullEditMode: () => undefined,
|
enableFullEditMode: () => undefined,
|
||||||
mode: "storage",
|
mode: "storage",
|
||||||
language: "en",
|
language: "en",
|
||||||
@@ -44,13 +42,22 @@ class HcLovelace extends LitElement {
|
|||||||
deleteConfig: async () => undefined,
|
deleteConfig: async () => undefined,
|
||||||
setEditMode: () => undefined,
|
setEditMode: () => undefined,
|
||||||
};
|
};
|
||||||
return html`
|
return this.lovelaceConfig.views[index].panel
|
||||||
<hui-view
|
? html`
|
||||||
.hass=${this.hass}
|
<hui-panel-view
|
||||||
.lovelace=${lovelace}
|
.hass=${this.hass}
|
||||||
.index=${index}
|
.lovelace=${lovelace}
|
||||||
></hui-view>
|
.config=${this.lovelaceConfig.views[index]}
|
||||||
`;
|
></hui-panel-view>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<hui-view
|
||||||
|
.hass=${this.hass}
|
||||||
|
.lovelace=${lovelace}
|
||||||
|
.index=${index}
|
||||||
|
columns="2"
|
||||||
|
></hui-view>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps) {
|
protected updated(changedProps) {
|
||||||
@@ -66,7 +73,7 @@ class HcLovelace extends LitElement {
|
|||||||
|
|
||||||
if (configBackground) {
|
if (configBackground) {
|
||||||
(this.shadowRoot!.querySelector(
|
(this.shadowRoot!.querySelector(
|
||||||
"hui-view"
|
"hui-view, hui-panel-view"
|
||||||
) as HTMLElement)!.style.setProperty(
|
) as HTMLElement)!.style.setProperty(
|
||||||
"--lovelace-background",
|
"--lovelace-background",
|
||||||
configBackground
|
configBackground
|
||||||
|
@@ -3,12 +3,7 @@ import {
|
|||||||
getAuth,
|
getAuth,
|
||||||
UnsubscribeFunc,
|
UnsubscribeFunc,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import {
|
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||||
customElement,
|
|
||||||
html,
|
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
|
||||||
import { CAST_NS } from "../../../../src/cast/const";
|
import { CAST_NS } from "../../../../src/cast/const";
|
||||||
import {
|
import {
|
||||||
ConnectMessage,
|
ConnectMessage,
|
||||||
@@ -36,13 +31,13 @@ let resourcesLoaded = false;
|
|||||||
|
|
||||||
@customElement("hc-main")
|
@customElement("hc-main")
|
||||||
export class HcMain extends HassElement {
|
export class HcMain extends HassElement {
|
||||||
@internalProperty() private _showDemo = false;
|
@property() private _showDemo = false;
|
||||||
|
|
||||||
@internalProperty() private _lovelaceConfig?: LovelaceConfig;
|
@property() private _lovelaceConfig?: LovelaceConfig;
|
||||||
|
|
||||||
@internalProperty() private _lovelacePath: string | number | null = null;
|
@property() private _lovelacePath: string | number | null = null;
|
||||||
|
|
||||||
@internalProperty() private _error?: string;
|
@property() private _error?: string;
|
||||||
|
|
||||||
private _unsubLovelace?: UnsubscribeFunc;
|
private _unsubLovelace?: UnsubscribeFunc;
|
||||||
|
|
||||||
@@ -87,7 +82,6 @@ export class HcMain extends HassElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.lovelaceConfig=${this._lovelaceConfig}
|
.lovelaceConfig=${this._lovelaceConfig}
|
||||||
.viewPath=${this._lovelacePath}
|
.viewPath=${this._lovelacePath}
|
||||||
.urlPath=${this._urlPath}
|
|
||||||
@config-refresh=${this._generateLovelaceConfig}
|
@config-refresh=${this._generateLovelaceConfig}
|
||||||
></hc-lovelace>
|
></hc-lovelace>
|
||||||
`;
|
`;
|
||||||
@@ -198,8 +192,6 @@ export class HcMain extends HassElement {
|
|||||||
this._handleNewLovelaceConfig(lovelaceConfig)
|
this._handleNewLovelaceConfig(lovelaceConfig)
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
|
||||||
console.log("Error fetching Lovelace configuration", err, msg);
|
|
||||||
// Generate a Lovelace config.
|
// Generate a Lovelace config.
|
||||||
this._unsubLovelace = () => undefined;
|
this._unsubLovelace = () => undefined;
|
||||||
await this._generateLovelaceConfig();
|
await this._generateLovelaceConfig();
|
||||||
@@ -216,7 +208,9 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,6 +233,9 @@ 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();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +256,14 @@ 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.5 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 532 B After Width: | Height: | Size: 767 B |
Before Width: | Height: | Size: 535 B After Width: | Height: | Size: 803 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: 7.1 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 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: 59 KiB After Width: | Height: | Size: 62 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: 184 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 111 KiB |