Compare commits

..

1 Commits

Author SHA1 Message Date
Paulus Schoutsen 368973b668 Add app alias 2020-06-21 12:37:12 -07:00
826 changed files with 15142 additions and 48283 deletions
+4 -8
View File
@@ -1,7 +1,7 @@
{
"extends": [
"airbnb-typescript/base",
"plugin:@typescript-eslint/recommended",
"airbnb-typescript/base",
"plugin:wc/recommended",
"plugin:lit/recommended",
"prettier",
@@ -45,16 +45,16 @@
"func-names": 0,
"prefer-arrow-callback": 0,
"no-underscore-dangle": 0,
"no-var": 0,
"strict": 0,
"prefer-spread": 0,
"no-plusplus": 0,
"no-bitwise": 2,
"no-bitwise": 0,
"comma-dangle": 0,
"vars-on-top": 0,
"no-continue": 0,
"no-param-reassign": 0,
"no-multi-assign": 0,
"no-console": 2,
"radix": 0,
"no-alert": 0,
"no-return-await": 0,
@@ -66,11 +66,7 @@
"import/prefer-default-export": 0,
"import/no-unresolved": 0,
"import/no-cycle": 0,
"import/extensions": [
2,
"ignorePackages",
{ "ts": "never", "js": "never" }
],
"import/extensions": 0,
"no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"],
"object-curly-newline": 0,
"default-case": 0,
+1 -1
View File
@@ -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
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
your issue in a different browser and be sure to include your findings.
+4 -2
View File
@@ -34,8 +34,10 @@ jobs:
run: yarn install
env:
CI: true
- name: Build resources
run: ./node_modules/.bin/gulp gen-icons-json build-translations gather-gallery-demos
- name: Build icons
run: ./node_modules/.bin/gulp gen-icons-json
- name: Build translations
run: ./node_modules/.bin/gulp build-translations
- name: Run eslint
run: ./node_modules/.bin/eslint '{**/src,src}/**/*.{js,ts,html}' --ignore-path .gitignore
- name: Run tsc
-60
View File
@@ -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
+1 -1
View File
@@ -24,7 +24,7 @@ dist
.vscode/*
!.vscode/extensions.json
# Cast dev settings
# Cast dev settings
src/cast/dev_const.ts
# Secrets
+3 -2
View File
@@ -57,7 +57,7 @@ module.exports.babelOptions = ({ latestBuild }) => ({
].filter(Boolean),
plugins: [
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
!latestBuild && [
[
"@babel/plugin-proposal-object-rest-spread",
{ loose: true, useBuiltIns: true },
],
@@ -73,7 +73,7 @@ module.exports.babelOptions = ({ latestBuild }) => ({
require("@babel/plugin-proposal-class-properties").default,
{ loose: true },
],
].filter(Boolean),
],
});
// Are already ES5, cause warnings when babelified.
@@ -178,6 +178,7 @@ module.exports.config = {
publicPath: publicPath(latestBuild, paths.hassio_publicPath),
isProdBuild,
latestBuild,
dontHash: new Set(["entrypoint"]),
};
},
+6 -39
View File
@@ -90,6 +90,8 @@ gulp.task("gen-pages-prod", (done) => {
});
gulp.task("gen-index-app-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 = renderTemplate("index", {
latestAppJS: "/frontend_latest/app.js",
latestCoreJS: "/frontend_latest/core.js",
@@ -199,6 +201,8 @@ gulp.task("gen-index-cast-prod", (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", {
latestDemoJS: "/frontend_latest/main.js",
@@ -236,6 +240,8 @@ gulp.task("gen-index-demo-prod", (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", {
latestGalleryJS: "./frontend_latest/entrypoint.js",
});
@@ -263,42 +269,3 @@ gulp.task("gen-index-gallery-prod", (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" }
);
}
+2 -38
View File
@@ -1,10 +1,7 @@
// Run demo develop mode
const gulp = require("gulp");
const fs = require("fs");
const path = require("path");
const env = require("../env");
const paths = require("../paths");
require("./clean.js");
require("./translations.js");
@@ -15,31 +12,6 @@ require("./service-worker.js");
require("./entry-html.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(
"develop-gallery",
gulp.series(
@@ -48,11 +20,7 @@ gulp.task(
},
"clean-gallery",
"translations-enable-merge-backend",
gulp.parallel(
"gen-icons-json",
"build-translations",
"gather-gallery-demos"
),
gulp.parallel("gen-icons-json", "build-translations"),
"copy-static-gallery",
"gen-index-gallery-dev",
env.useRollup() ? "rollup-dev-server-gallery" : "webpack-dev-server-gallery"
@@ -67,11 +35,7 @@ gulp.task(
},
"clean-gallery",
"translations-enable-merge-backend",
gulp.parallel(
"gen-icons-json",
"build-translations",
"gather-gallery-demos"
),
gulp.parallel("gen-icons-json", "build-translations"),
"copy-static-gallery",
env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery",
"gen-index-gallery-prod"
+1 -9
View File
@@ -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 ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi");
const REMOVED_ICONS_PATH = path.resolve(__dirname, "../removedIcons.json");
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 chunks = [];
const CHUNK_SIZE = 50000;
@@ -77,7 +69,7 @@ const findDifferentiator = (curString, prevString) => {
};
gulp.task("gen-icons-json", (done) => {
const meta = addRemovedMeta(getMeta());
const meta = getMeta();
const split = splitBySize(meta);
if (!fs.existsSync(OUTPUT_DIR)) {
+20 -2
View File
@@ -11,6 +11,24 @@ require("./webpack.js");
require("./compress.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(
"develop-hassio",
gulp.series(
@@ -19,7 +37,7 @@ gulp.task(
},
"clean-hassio",
"gen-icons-json",
"gen-index-hassio-dev",
writeEntrypointJS,
env.useRollup() ? "rollup-watch-hassio" : "webpack-watch-hassio"
)
);
@@ -33,7 +51,7 @@ gulp.task(
"clean-hassio",
"gen-icons-json",
env.useRollup() ? "rollup-prod-hassio" : "webpack-prod-hassio",
"gen-index-hassio-prod",
writeEntrypointJS,
...// Don't compress running tests
(env.isTest() ? [] : ["compress-hassio"])
)
-5
View File
@@ -34,11 +34,6 @@ module.exports = {
hassio_dir: path.resolve(__dirname, "../hassio"),
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",
translations_src: path.resolve(__dirname, "../src/translations"),
-1
View File
@@ -1 +0,0 @@
[]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

+23 -16
View File
@@ -37,21 +37,23 @@
<body>
<%= renderTemplate('_js_base') %>
<script>
import("<%= latestLauncherJS %>");
window.latestJS = true;
<script type="module" crossorigin="use-credentials">
import "<%= latestLauncherJS %>";
</script>
<script>
if (!window.latestJS) {
<% if (useRollup) { %>
_ls("/static/js/s.min.js").onload = function() {
System.import("<%= es5LauncherJS %>");
};
<% } else { %>
_ls("<%= es5LauncherJS %>");
<% } %>
}
<script nomodule>
(function() {
// // Safari 10.1 supports type=module but ignores nomodule, so we add this check.
if (!isS101) {
<% if (useRollup) { %>
_ls("/static/js/s.min.js").onload = function() {
System.import("<%= es5LauncherJS %>");
};
<% } else { %>
_ls("<%= es5LauncherJS %>");
<% } %>
}
})();
</script>
<hc-layout subtitle="FAQ">
@@ -212,8 +214,13 @@
Chromecast is a technology developed by Google, and is available on:
</p>
<ul>
<li>Google Chrome (all platforms except iOS)</li>
<li>Microsoft Edge (all platforms)</li>
<li>Google Chrome (all platforms except on iOS)</li>
<li>
Microsoft Edge (all platforms,
<a href="https://www.microsoftedgeinsider.com" target="_blank"
>dev and canary builds only</a
>)
</li>
</ul>
</div>
@@ -246,7 +253,7 @@ http:
<script>
var _gaq = [["_setAccount", "UA-57927901-9"], ["_trackPageview"]];
(function (d, t) {
(function(d, t) {
var g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
g.src =
+15 -13
View File
@@ -28,21 +28,23 @@
<hc-connect></hc-connect>
<script>
import("<%= latestLauncherJS %>");
window.latestJS = true;
<script type="module" crossorigin="use-credentials">
import "<%= latestLauncherJS %>";
</script>
<script>
if (!window.latestJS) {
<% if (useRollup) { %>
_ls("/static/js/s.min.js").onload = function() {
System.import("<%= es5LauncherJS %>");
};
<% } else { %>
_ls("<%= es5LauncherJS %>");
<% } %>
}
<script nomodule>
(function() {
// // Safari 10.1 supports type=module but ignores nomodule, so we add this check.
if (!isS101) {
<% if (useRollup) { %>
_ls("/static/js/s.min.js").onload = function() {
System.import("<%= es5LauncherJS %>");
};
<% } else { %>
_ls("<%= es5LauncherJS %>");
<% } %>
}
})();
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+2 -3
View File
@@ -1,4 +1,3 @@
import "../../../src/resources/safari-14-attachshadow-patch";
import "../../../src/resources/ha-style";
import "../../../src/resources/roboto";
import "~app/resources/ha-style";
import "~app/resources/roboto";
import "./layout/hc-connect";
+4 -5
View File
@@ -8,7 +8,6 @@ import {
html,
LitElement,
property,
internalProperty,
TemplateResult,
} from "lit-element";
import { CastManager } from "../../../../src/cast/cast_manager";
@@ -29,7 +28,7 @@ import {
getLovelaceCollection,
LovelaceConfig,
} 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 "./hc-layout";
import "@material/mwc-button/mwc-button";
@@ -42,13 +41,13 @@ class HcCast extends LitElement {
@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 {
if (this.lovelaceConfig === undefined) {
return html` <hass-loading-screen no-toolbar></hass-loading-screen>> `;
return html` <loading-screen></loading-screen>> `;
}
const error =
+9 -9
View File
@@ -17,8 +17,8 @@ import {
customElement,
html,
LitElement,
property,
TemplateResult,
internalProperty,
} from "lit-element";
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
@@ -27,7 +27,7 @@ import {
saveTokens,
} from "../../../../src/common/auth/token_storage";
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 "./hc-layout";
@@ -60,19 +60,19 @@ const INTRO = html`
@customElement("hc-connect")
export class HcConnect extends LitElement {
@internalProperty() private loading = false;
@property() private loading = false;
// If we had stored credentials but we cannot connect,
// 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;
@@ -98,7 +98,7 @@ export class HcConnect extends LitElement {
}
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) {
+7 -102
View File
@@ -1,65 +1,18 @@
/* eslint-disable no-undef */
import { CAST_NS } from "../../../src/cast/const";
import { HassMessage } from "../../../src/cast/receiver_messages";
import "../../../src/resources/custom-card-support";
import { CAST_NS } from "~app/cast/const";
import { HassMessage } from "~app/cast/receiver_messages";
import "~app/resources/custom-card-support";
import { castContext } from "./cast_context";
import { HcMain } from "./layout/hc-main";
import { ReceivedMessage } from "./types";
const lovelaceController = new HcMain();
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 controller = new HcMain();
document.body.append(controller);
const options = new cast.framework.CastReceiverOptions();
options.disableIdleTimeout = true;
options.customNamespaces = {
// @ts-ignore
[CAST_NS]: cast.framework.system.MessageType.JSON,
};
@@ -77,61 +30,13 @@ options.uiConfig = new cast.framework.ui.UiConfig();
// @ts-ignore
options.uiConfig.touchScreenOptimizedApp = true;
castContext.setInactivityTimeout(86400); // 1 day
castContext.addCustomMessageListener(
CAST_NS,
// @ts-ignore
(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;
msg.senderId = ev.senderId;
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();
}
controller.processIncomingMessage(msg);
}
);
+3 -9
View File
@@ -1,10 +1,4 @@
import {
customElement,
html,
property,
internalProperty,
TemplateResult,
} from "lit-element";
import { customElement, html, property, TemplateResult } from "lit-element";
import { mockHistory } from "../../../../demo/src/stubs/history";
import { LovelaceConfig } from "../../../../src/data/lovelace";
import {
@@ -19,9 +13,9 @@ import "./hc-lovelace";
@customElement("hc-demo")
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 {
if (!this._lovelaceConfig) {
+1 -1
View File
@@ -11,7 +11,7 @@ import { HomeAssistant } from "../../../../src/types";
@customElement("hc-launch-screen")
class HcLaunchScreen extends LitElement {
@property({ attribute: false }) public hass?: HomeAssistant;
@property() public hass?: HomeAssistant;
@property() public error?: string;
+20 -13
View File
@@ -9,20 +9,19 @@ import {
} from "lit-element";
import { LovelaceConfig } from "../../../../src/data/lovelace";
import { Lovelace } from "../../../../src/panels/lovelace/types";
import "../../../../src/panels/lovelace/views/hui-panel-view";
import "../../../../src/panels/lovelace/views/hui-view";
import { HomeAssistant } from "../../../../src/types";
import "./hc-launch-screen";
@customElement("hc-lovelace")
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;
public urlPath?: string | null;
protected render(): TemplateResult {
const index = this._viewIndex;
if (index === undefined) {
@@ -36,7 +35,6 @@ class HcLovelace extends LitElement {
const lovelace: Lovelace = {
config: this.lovelaceConfig,
editMode: false,
urlPath: this.urlPath!,
enableFullEditMode: () => undefined,
mode: "storage",
language: "en",
@@ -44,13 +42,22 @@ class HcLovelace extends LitElement {
deleteConfig: async () => undefined,
setEditMode: () => undefined,
};
return html`
<hui-view
.hass=${this.hass}
.lovelace=${lovelace}
.index=${index}
></hui-view>
`;
return this.lovelaceConfig.views[index].panel
? html`
<hui-panel-view
.hass=${this.hass}
.lovelace=${lovelace}
.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) {
@@ -66,7 +73,7 @@ class HcLovelace extends LitElement {
if (configBackground) {
(this.shadowRoot!.querySelector(
"hui-view"
"hui-view, hui-panel-view"
) as HTMLElement)!.style.setProperty(
"--lovelace-background",
configBackground
+19 -12
View File
@@ -3,12 +3,7 @@ import {
getAuth,
UnsubscribeFunc,
} from "home-assistant-js-websocket";
import {
customElement,
html,
internalProperty,
TemplateResult,
} from "lit-element";
import { customElement, html, property, TemplateResult } from "lit-element";
import { CAST_NS } from "../../../../src/cast/const";
import {
ConnectMessage,
@@ -36,13 +31,13 @@ let resourcesLoaded = false;
@customElement("hc-main")
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;
@@ -87,7 +82,6 @@ export class HcMain extends HassElement {
.hass=${this.hass}
.lovelaceConfig=${this._lovelaceConfig}
.viewPath=${this._lovelacePath}
.urlPath=${this._urlPath}
@config-refresh=${this._generateLovelaceConfig}
></hc-lovelace>
`;
@@ -216,7 +210,9 @@ export class HcMain extends HassElement {
}
this._showDemo = false;
this._lovelacePath = msg.viewPath;
if (castContext.getDeviceCapabilities().touch_input_supported) {
this._breakFree();
}
this._sendStatus();
}
@@ -239,6 +235,9 @@ export class HcMain extends HassElement {
this._showDemo = true;
this._lovelacePath = "overview";
this._sendStatus();
if (castContext.getDeviceCapabilities().touch_input_supported) {
this._breakFree();
}
});
}
@@ -259,6 +258,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) {
castContext.sendCustomMessage(CAST_NS, senderId, response);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 B

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

+2 -2
View File
@@ -26,9 +26,9 @@ export const demoThemeJimpower = () => ({
"switch-checked-color": "var(--accent-color)",
"paper-dialog-background-color": "#434954",
"secondary-text-color": "#5294E2",
"error-color": "#E45E65",
"google-red-500": "#E45E65",
"divider-color": "rgba(0, 0, 0, .12)",
"success-color": "#39E949",
"google-green-500": "#39E949",
"switch-unchecked-button-color": "var(--disabled-text-color)",
"label-badge-border-color": "green",
"paper-listbox-color": "var(--primary-color)",
+2 -2
View File
@@ -27,9 +27,9 @@ export const demoThemeKernehed = () => ({
"switch-checked-color": "var(--accent-color)",
"paper-dialog-background-color": "#292929",
"secondary-text-color": "#b58e31",
"error-color": "#b58e31",
"google-red-500": "#b58e31",
"divider-color": "rgba(0, 0, 0, .12)",
"success-color": "#2980b9",
"google-green-500": "#2980b9",
"switch-unchecked-button-color": "var(--disabled-text-color)",
"label-badge-border-color": "green",
"paper-listbox-color": "#777777",
+3 -2
View File
@@ -4,7 +4,7 @@ import {
customElement,
html,
LitElement,
internalProperty,
property,
TemplateResult,
} from "lit-element";
import { CastManager } from "../../../src/cast/cast_manager";
@@ -20,7 +20,7 @@ import { HomeAssistant } from "../../../src/types";
class CastDemoRow extends LitElement implements LovelaceRow {
public hass!: HomeAssistant;
@internalProperty() private _castManager?: CastManager | null;
@property() private _castManager?: CastManager | null;
public setConfig(_config: CastConfig): void {
// No config possible.
@@ -52,6 +52,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
});
mgr.castContext.addEventListener(
// eslint-disable-next-line no-undef
// @ts-ignore
cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
(ev) => {
// On Android, opening a new session always results in SESSION_RESUMED.
+5 -6
View File
@@ -1,16 +1,15 @@
import "@material/mwc-button";
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
html,
LitElement,
property,
internalProperty,
TemplateResult,
} from "lit-element";
import { until } from "lit-html/directives/until";
import "../../../src/components/ha-card";
import "../../../src/components/ha-circular-progress";
import { LovelaceCardConfig } from "../../../src/data/lovelace";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
import { Lovelace, LovelaceCard } from "../../../src/panels/lovelace/types";
@@ -22,11 +21,11 @@ import {
} from "../configs/demo-configs";
export class HADemoCard extends LitElement implements LovelaceCard {
@property({ attribute: false }) public lovelace?: Lovelace;
@property() public lovelace?: Lovelace;
@property({ attribute: false }) public hass!: MockHomeAssistant;
@property() public hass!: MockHomeAssistant;
@internalProperty() private _switching?: boolean;
@property() private _switching?: boolean;
private _hidden = localStorage.hide_demo_card;
@@ -50,7 +49,7 @@ export class HADemoCard extends LitElement implements LovelaceCard {
<div class="picker">
<div class="label">
${this._switching
? html`<ha-circular-progress active></ha-circular-progress>`
? html` <paper-spinner-lite active></paper-spinner-lite> `
: until(
selectedDemoConfig.then(
(conf) => html`
-1
View File
@@ -1,4 +1,3 @@
import "../../src/resources/safari-14-attachshadow-patch";
import "@polymer/polymer/lib/elements/dom-if";
import "@polymer/polymer/lib/elements/dom-repeat";
import "../../src/resources/ha-style";
+15 -15
View File
@@ -86,26 +86,26 @@
<%= renderTemplate('_js_base') %>
<%= renderTemplate('_preload_roboto') %>
<script>
import("<%= latestDemoJS %>");
window.latestJS = true;
</script>
<script type="module" src="<%= latestDemoJS %>"></script>
<script>
if (!window.latestJS) {
<% if (useRollup) { %>
_ls("/static/js/s.min.js").onload = function() {
System.import("<%= es5DemoJS %>");
};
<% } else { %>
_ls("<%= es5DemoJS %>");
<% } %>
}
<script nomodule>
(function() {
// // Safari 10.1 supports type=module but ignores nomodule, so we add this check.
if (!isS101) {
<% if (useRollup) { %>
_ls("/static/js/s.min.js").onload = function() {
System.import("<%= es5DemoJS %>");
};
<% } else { %>
_ls("<%= es5DemoJS %>");
<% } %>
}
})();
</script>
<script>
var _gaq = [["_setAccount", "UA-57927901-5"], ["_trackPageview"]];
(function (d, t) {
(function(d, t) {
var g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
g.src =
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 111 KiB

+2 -2
View File
@@ -2,8 +2,8 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../src/components/ha-switch";
import "../../../src/components/ha-formfield";
import "~app/components/ha-switch";
import "~app/components/ha-formfield";
import "./demo-card";
class DemoCards extends PolymerElement {
+1 -1
View File
@@ -2,8 +2,8 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../src/components/ha-card";
import "../../../src/dialogs/more-info/controls/more-info-content";
import "../../../src/state-summary/state-card-content";
import "./more-info-content";
class DemoMoreInfo extends PolymerElement {
static get template() {
@@ -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/dialogs/more-info/state_more_info_control";
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);
+21
View File
@@ -420,6 +420,15 @@ export default {
last_changed: "2018-07-19T10:44:46.105940+00:00",
last_updated: "2018-07-19T10:44:46.105940+00:00",
},
"weblink.router": {
entity_id: "weblink.router",
state: "http://192.168.1.1",
attributes: {
friendly_name: "Router",
},
last_changed: "2018-07-19T10:44:46.107286+00:00",
last_updated: "2018-07-19T10:44:46.107286+00:00",
},
"group.all_plants": {
entity_id: "group.all_plants",
state: "ok",
@@ -1081,6 +1090,18 @@ export default {
last_changed: "2018-07-19T10:44:46.510448+00:00",
last_updated: "2018-07-19T10:44:46.510448+00:00",
},
"history_graph.recent_switches": {
entity_id: "history_graph.recent_switches",
state: "unknown",
attributes: {
hours_to_show: 1,
refresh: 60,
entity_id: ["switch.ac", "switch.decorative_lights"],
friendly_name: "Recent Switches",
},
last_changed: "2018-07-19T10:44:46.512351+00:00",
last_updated: "2018-07-19T10:44:46.512351+00:00",
},
"scene.switch_on_and_off": {
entity_id: "scene.switch_on_and_off",
state: "scening",
+1 -1
View File
@@ -3,10 +3,10 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../src/components/ha-card";
import { SUPPORT_BRIGHTNESS } from "../../../src/data/light";
import "../../../src/dialogs/more-info/controls/more-info-content";
import { getEntity } from "../../../src/fake_data/entity";
import { provideHass } from "../../../src/fake_data/provide_hass";
import "../components/demo-more-infos";
import "../components/more-info-content";
const ENTITIES = [
getEntity("light", "bed_light", "on", {
+7 -6
View File
@@ -1,18 +1,19 @@
import "@polymer/app-layout/app-header-layout/app-header-layout";
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import "../../src/components/ha-icon-button";
import "../../src/components/ha-icon";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../src/components/ha-card";
import "../../src/components/ha-icon";
import "../../src/components/ha-icon-button";
import "../../src/managers/notification-manager";
import "../../src/styles/polymer-ha-style";
// eslint-disable-next-line import/extensions
import { DEMOS } from "../build/import-demos";
// eslint-disable-next-line no-undef
const DEMOS = require.context("./demos", true, /^(.*\.(ts$))[^.]*$/im);
const fixPath = (path) => path.substr(2, path.length - 5);
@@ -162,7 +163,7 @@ class HaGallery extends PolymerElement {
},
_demos: {
type: Array,
value: Object.keys(DEMOS),
value: DEMOS.keys().map(fixPath),
},
_lovelaceDemos: {
type: Array,
@@ -209,7 +210,7 @@ class HaGallery extends PolymerElement {
while (root.lastChild) root.removeChild(root.lastChild);
if (demo) {
DEMOS[demo]();
DEMOS(`./${demo}.ts`);
const el = document.createElement(demo);
root.appendChild(el);
}
@@ -21,7 +21,7 @@ import { filterAndSort } from "../components/hassio-filter-addons";
import { hassioStyle } from "../resources/hassio-style";
class HassioAddonRepositoryEl extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public hass!: HomeAssistant;
@property() public repo!: HassioAddonRepository;
+8 -26
View File
@@ -1,11 +1,9 @@
import "@material/mwc-icon-button/mwc-icon-button";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import "@material/mwc-list/mwc-list-item";
import { mdiDotsVertical } from "@mdi/js";
import {
css,
CSSResult,
internalProperty,
LitElement,
property,
PropertyValues,
@@ -20,12 +18,11 @@ import {
HassioAddonRepository,
reloadHassioAddons,
} from "../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
import "../../../src/layouts/hass-loading-screen";
import "../../../src/layouts/hass-tabs-subpage";
import "../../../src/layouts/loading-screen";
import { HomeAssistant, Route } from "../../../src/types";
import { showRepositoriesDialog } from "../dialogs/repositories/show-dialog-repositories";
import { supervisorTabs } from "../hassio-tabs";
import { supervisorTabs } from "../hassio-panel";
import "./hassio-addon-repository";
const sortRepos = (a: HassioAddonRepository, b: HassioAddonRepository) => {
@@ -55,7 +52,7 @@ class HassioAddonStore extends LitElement {
@property({ attribute: false }) private _repos?: HassioAddonRepository[];
@internalProperty() private _filter?: string;
@property() private _filter?: string;
public async refreshData() {
this._repos = undefined;
@@ -99,23 +96,19 @@ class HassioAddonStore extends LitElement {
.tabs=${supervisorTabs}
>
<span slot="header">Add-on store</span>
<ha-button-menu
corner="BOTTOM_START"
slot="toolbar-icon"
@action=${this._handleAction}
>
<ha-button-menu corner="BOTTOM_START" slot="toolbar-icon">
<mwc-icon-button slot="trigger" alt="menu">
<ha-svg-icon path=${mdiDotsVertical}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item>
<mwc-list-item @tap=${this._manageRepositories}>
Repositories
</mwc-list-item>
<mwc-list-item>
<mwc-list-item @tap=${this.refreshData}>
Reload
</mwc-list-item>
</ha-button-menu>
${repos.length === 0
? html`<hass-loading-screen no-toolbar></hass-loading-screen>`
? html`<loading-screen></loading-screen>`
: html`
<div class="search">
<search-input
@@ -149,17 +142,6 @@ class HassioAddonStore extends LitElement {
this._loadData();
}
private _handleAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
this._manageRepositories();
break;
case 1:
this.refreshData();
break;
}
}
private apiCalled(ev) {
if (ev.detail.success) {
this._loadData();
@@ -180,7 +162,7 @@ class HassioAddonStore extends LitElement {
this._repos.sort(sortRepos);
this._addons = addonsInfo.addons;
} catch (err) {
alert(extractApiErrorMessage(err));
alert("Failed to fetch add-on info");
}
}
@@ -9,7 +9,6 @@ import {
html,
LitElement,
property,
internalProperty,
PropertyValues,
TemplateResult,
} from "lit-element";
@@ -28,7 +27,6 @@ import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
import { hassioStyle } from "../../resources/hassio-style";
import "../../../../src/components/buttons/ha-progress-button";
@customElement("hassio-addon-audio")
class HassioAddonAudio extends LitElement {
@@ -36,15 +34,15 @@ class HassioAddonAudio extends LitElement {
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@property() private _error?: string;
@internalProperty() private _inputDevices?: HassioHardwareAudioDevice[];
@property() private _inputDevices?: HassioHardwareAudioDevice[];
@internalProperty() private _outputDevices?: HassioHardwareAudioDevice[];
@property() private _outputDevices?: HassioHardwareAudioDevice[];
@internalProperty() private _selectedInput!: null | string;
@property() private _selectedInput!: null | string;
@internalProperty() private _selectedOutput!: null | string;
@property() private _selectedOutput!: null | string;
protected render(): TemplateResult {
return html`
@@ -92,9 +90,7 @@ class HassioAddonAudio extends LitElement {
</paper-dropdown-menu>
</div>
<div class="card-actions">
<ha-progress-button @click=${this._saveSettings}>
Save
</ha-progress-button>
<mwc-button @click=${this._saveSettings}>Save</mwc-button>
</div>
</ha-card>
`;
@@ -111,7 +107,7 @@ class HassioAddonAudio extends LitElement {
display: block;
}
.errors {
color: var(--error-color);
color: var(--google-red-500);
margin-bottom: 16px;
}
paper-item {
@@ -175,10 +171,7 @@ class HassioAddonAudio extends LitElement {
}
}
private async _saveSettings(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
private async _saveSettings(): Promise<void> {
this._error = undefined;
const data: HassioAddonSetOptionParams = {
audio_input:
@@ -188,14 +181,12 @@ class HassioAddonAudio extends LitElement {
};
try {
await setHassioAddonOption(this.hass, this.addon.slug, data);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch {
this._error = "Failed to set addon audio device";
}
button.progress = false;
if (!this._error && this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
}
}
@@ -1,3 +1,4 @@
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
@@ -11,7 +12,6 @@ import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
import "../../../../src/components/ha-circular-progress";
import "./hassio-addon-audio";
import "./hassio-addon-config";
import "./hassio-addon-network";
@@ -24,7 +24,7 @@ class HassioAddonConfigDashboard extends LitElement {
protected render(): TemplateResult {
if (!this.addon) {
return html`<ha-circular-progress active></ha-circular-progress>`;
return html` <paper-spinner-lite active></paper-spinner-lite> `;
}
return html`
<div class="content">
@@ -5,7 +5,6 @@ import {
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
PropertyValues,
@@ -13,7 +12,6 @@ import {
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-card";
import "../../../../src/components/ha-yaml-editor";
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
@@ -22,7 +20,6 @@ import {
HassioAddonSetOptionParams,
setHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { showConfirmationDialog } from "../../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
@@ -35,7 +32,7 @@ class HassioAddonConfig extends LitElement {
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@property() private _error?: string;
@property({ type: Boolean }) private _configHasChanged = false;
@@ -57,20 +54,50 @@ class HassioAddonConfig extends LitElement {
${valid ? "" : html` <div class="errors">Invalid YAML</div> `}
</div>
<div class="card-actions">
<ha-progress-button class="warning" @click=${this._resetTapped}>
<mwc-button class="warning" @click=${this._resetTapped}>
Reset to defaults
</ha-progress-button>
<ha-progress-button
</mwc-button>
<mwc-button
@click=${this._saveTapped}
.disabled=${!this._configHasChanged || !valid}
>
Save
</ha-progress-button>
</mwc-button>
</div>
</ha-card>
`;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
:host {
display: block;
}
ha-card {
display: block;
}
.card-actions {
display: flex;
justify-content: space-between;
}
.errors {
color: var(--google-red-500);
margin-top: 16px;
}
iron-autogrow-textarea {
width: 100%;
font-family: monospace;
}
.syntaxerror {
color: var(--google-red-500);
}
`,
];
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (changedProperties.has("addon")) {
@@ -83,10 +110,7 @@ class HassioAddonConfig extends LitElement {
this.requestUpdate();
}
private async _resetTapped(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
private async _resetTapped(): Promise<void> {
const confirmed = await showConfirmationDialog(this, {
title: this.addon.name,
text: "Are you sure you want to reset all your options?",
@@ -95,7 +119,6 @@ class HassioAddonConfig extends LitElement {
});
if (!confirmed) {
button.progress = false;
return;
}
@@ -113,17 +136,13 @@ class HassioAddonConfig extends LitElement {
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
this._error = `Failed to reset addon configuration, ${extractApiErrorMessage(
err
)}`;
this._error = `Failed to reset addon configuration, ${
err.body?.message || err
}`;
}
button.progress = false;
}
private async _saveTapped(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
private async _saveTapped(): Promise<void> {
let data: HassioAddonSetOptionParams;
this._error = undefined;
try {
@@ -143,45 +162,14 @@ class HassioAddonConfig extends LitElement {
path: "options",
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch (err) {
this._error = `Failed to save addon configuration, ${extractApiErrorMessage(
err
)}`;
this._error = `Failed to save addon configuration, ${
err.body?.message || err
}`;
}
if (!this._error && this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
button.progress = false;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
:host {
display: block;
}
ha-card {
display: block;
}
.card-actions {
display: flex;
justify-content: space-between;
}
.errors {
color: var(--error-color);
margin-top: 16px;
}
iron-autogrow-textarea {
width: 100%;
font-family: var(--code-font-family, monospace);
}
.syntaxerror {
color: var(--error-color);
}
`,
];
}
}
@@ -4,21 +4,18 @@ import {
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
PropertyValues,
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../../src/components/buttons/ha-progress-button";
import "../../../../src/components/ha-card";
import {
HassioAddonDetails,
HassioAddonSetOptionParams,
setHassioAddonOption,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { suggestAddonRestart } from "../../dialogs/suggestAddonRestart";
@@ -40,9 +37,9 @@ class HassioAddonNetwork extends LitElement {
@property({ attribute: false }) public addon!: HassioAddonDetails;
@internalProperty() private _error?: string;
@property() private _error?: string;
@internalProperty() private _config?: NetworkItem[];
@property() private _config?: NetworkItem[];
public connectedCallback(): void {
super.connectedCallback();
@@ -74,7 +71,7 @@ class HassioAddonNetwork extends LitElement {
<paper-input
@value-changed=${this._configChanged}
placeholder="disabled"
.value=${item.host ? String(item.host) : ""}
.value=${String(item.host)}
.container=${item.container}
no-label-float
></paper-input>
@@ -87,17 +84,38 @@ class HassioAddonNetwork extends LitElement {
</table>
</div>
<div class="card-actions">
<ha-progress-button class="warning" @click=${this._resetTapped}>
<mwc-button class="warning" @click=${this._resetTapped}>
Reset to defaults
</ha-progress-button>
<ha-progress-button @click=${this._saveTapped}>
Save
</ha-progress-button>
</mwc-button>
<mwc-button @click=${this._saveTapped}>Save</mwc-button>
</div>
</ha-card>
`;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
:host {
display: block;
}
ha-card {
display: block;
}
.errors {
color: var(--google-red-500);
margin-bottom: 16px;
}
.card-actions {
display: flex;
justify-content: space-between;
}
`,
];
}
protected update(changedProperties: PropertyValues): void {
super.update(changedProperties);
if (changedProperties.has("addon")) {
@@ -130,10 +148,7 @@ class HassioAddonNetwork extends LitElement {
});
}
private async _resetTapped(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
private async _resetTapped(): Promise<void> {
const data: HassioAddonSetOptionParams = {
network: null,
};
@@ -146,22 +161,17 @@ class HassioAddonNetwork extends LitElement {
path: "option",
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch (err) {
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
err
)}`;
this._error = `Failed to set addon network configuration, ${
err.body?.message || err
}`;
}
if (!this._error && this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
button.progress = false;
}
private async _saveTapped(ev: CustomEvent): Promise<void> {
const button = ev.currentTarget as any;
button.progress = true;
private async _saveTapped(): Promise<void> {
this._error = undefined;
const networkconfiguration = {};
this._config!.forEach((item) => {
@@ -180,38 +190,14 @@ class HassioAddonNetwork extends LitElement {
path: "option",
};
fireEvent(this, "hass-api-called", eventdata);
if (this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
} catch (err) {
this._error = `Failed to set addon network configuration, ${extractApiErrorMessage(
err
)}`;
this._error = `Failed to set addon network configuration, ${
err.body?.message || err
}`;
}
if (!this._error && this.addon?.state === "started") {
await suggestAddonRestart(this, this.hass, this.addon);
}
button.progress = false;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
:host {
display: block;
}
ha-card {
display: block;
}
.errors {
color: var(--error-color);
margin-bottom: 16px;
}
.card-actions {
display: flex;
justify-content: space-between;
}
`,
];
}
}
@@ -1,21 +1,19 @@
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import "../../../../src/components/ha-circular-progress";
import "../../../../src/components/ha-markdown";
import {
fetchHassioAddonDocumentation,
HassioAddonDetails,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import "../../../../src/layouts/hass-loading-screen";
import "../../../../src/layouts/loading-screen";
import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../../resources/hassio-style";
@@ -26,9 +24,9 @@ class HassioAddonDocumentationDashboard extends LitElement {
@property({ attribute: false }) public addon?: HassioAddonDetails;
@internalProperty() private _error?: string;
@property() private _error?: string;
@internalProperty() private _content?: string;
@property() private _content?: string;
public async connectedCallback(): Promise<void> {
super.connectedCallback();
@@ -37,7 +35,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
protected render(): TemplateResult {
if (!this.addon) {
return html`<ha-circular-progress active></ha-circular-progress>`;
return html` <paper-spinner-lite active></paper-spinner-lite> `;
}
return html`
<div class="content">
@@ -46,7 +44,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
<div class="card-content">
${this._content
? html`<ha-markdown .content=${this._content}></ha-markdown>`
: html`<hass-loading-screen no-toolbar></hass-loading-screen>`}
: html`<loading-screen></loading-screen>`}
</div>
</ha-card>
</div>
@@ -81,9 +79,9 @@ class HassioAddonDocumentationDashboard extends LitElement {
this.addon!.slug
);
} catch (err) {
this._error = `Failed to get addon documentation, ${extractApiErrorMessage(
err
)}`;
this._error = `Failed to get addon documentation, ${
err.body?.message || err
}`;
}
}
}
@@ -4,6 +4,7 @@ import {
mdiInformationVariant,
mdiMathLog,
} from "@mdi/js";
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
@@ -19,7 +20,6 @@ import {
HassioAddonDetails,
} from "../../../src/data/hassio/addon";
import "../../../src/layouts/hass-tabs-subpage";
import "../../../src/components/ha-circular-progress";
import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage";
import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types";
@@ -56,7 +56,7 @@ class HassioAddonDashboard extends LitElement {
protected render(): TemplateResult {
if (!this.addon) {
return html`<ha-circular-progress active></ha-circular-progress>`;
return html` <paper-spinner-lite active></paper-spinner-lite> `;
}
const addonTabs: PageNavigation[] = [

Some files were not shown because too many files have changed in this diff Show More