Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
igor-panteleev committed Jan 18, 2022
1 parent 8fc40b1 commit 0d5ed95
Show file tree
Hide file tree
Showing 18 changed files with 8,934 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 2020,
sourceType: "module",
},
extends: [
"plugin:@typescript-eslint/recommended",
],
rules: {},
};
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/node_modules/
/.rpt2_cache/
/dist
.idea
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dist
.vscode
.devcontainer
package-lock.json
*.md
*.yaml
*.yml
*.txt
9 changes: 9 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
semi: true,
trailingComma: "all",
singleQuote: false,
printWidth: 120,
tabWidth: 4,
bracketSameLine: true,
arrowParens: "avoid",
};
8,088 changes: 8,088 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "qr-code-card",
"version": "v1.0.0",
"description": "QR code card",
"keywords": [
"home-assistant",
"homeassistant",
"hass",
"lovelace",
"custom-cards"
],
"module": "qr-code-card.js",
"license": "MIT",
"dependencies": {
"@polymer/paper-dropdown-menu": "^3.2.0",
"@polymer/paper-item": "^3.0.1",
"@polymer/paper-listbox": "^3.0.1",
"compare-versions": "^4.0.1",
"custom-card-helpers": "^1.7.2",
"lit": "^2.0.0-rc.2",
"qrcode": "^1.4.4"
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.14.5",
"@rollup/plugin-json": "^4.1.0",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.24.0",
"eslint-plugin-prettier": "^4.0.0",
"prettier": "^2.4.1",
"rollup": "^2.60.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-serve": "^1.1.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.30.0",
"typescript": "^4.4.3"
},
"scripts": {
"start": "rollup -c --watch",
"build": "npm run lint && npm run rollup",
"lint": "eslint src/*.ts",
"rollup": "rollup -c"
}
}
45 changes: 45 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import nodeResolve from "rollup-plugin-node-resolve";
import babel from "rollup-plugin-babel";
import {terser} from "rollup-plugin-terser";
import serve from "rollup-plugin-serve";
import json from "@rollup/plugin-json";

const dev = process.env.ROLLUP_WATCH;

const serveopts = {
contentBase: ["./dist"],
host: "0.0.0.0",
port: 5000,
allowCrossOrigin: true,
headers: {
"Access-Control-Allow-Origin": "*",
},
};

const plugins = [
nodeResolve({
browser: true,
preferBuiltins: false
}),
commonjs(),
typescript(),
json(),
babel({
exclude: "node_modules/**",
}),
dev && serve(serveopts),
!dev && terser(),
];

export default [
{
input: "src/qr-code-card.ts",
output: {
dir: "dist",
format: "es",
},
plugins: [...plugins],
},
];
2 changes: 2 additions & 0 deletions src/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const CARD_CUSTOM_ELEMENT_NAME = "qr-code-card";
export const EDITOR_CUSTOM_ELEMENT_NAME = "qr-code-card-editor";
219 changes: 219 additions & 0 deletions src/editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent, HomeAssistant, LovelaceCardEditor } from "custom-card-helpers";

import {
EntitySourceConfig,
QRCodeCardConfig,
TextSourceConfig,
TranslatableString,
WiFiSourceConfig
} from "./types/types";
import { localizeWithHass } from "./localize/localize";
import { SourceType } from "./models/source-type";
import { AuthenticationType } from "./models/authentication-type";
import { EDITOR_CUSTOM_ELEMENT_NAME } from "./const";


@customElement(EDITOR_CUSTOM_ELEMENT_NAME)
export class QRCodeCardEditor extends LitElement implements LovelaceCardEditor {
@property({attribute: false}) public hass?: HomeAssistant;
@state() private _config?: QRCodeCardConfig;
private _initialized = false;

public setConfig(config: QRCodeCardConfig): void {
this._config = config;
}

protected shouldUpdate(): boolean {
if (!this._initialized) {
this._initialize();
}
return true;
}

get _source(): SourceType | undefined {
return this._config?.source;
}

get _text(): string {
const config = this._config as TextSourceConfig | undefined;
return config?.text || "";
}

get _auth_type(): AuthenticationType | undefined {
const config = this._config as WiFiSourceConfig | undefined;
return config?.auth_type;
}

get _ssid(): string {
const config = this._config as WiFiSourceConfig | undefined;
return config?.ssid || "";
}

get _password(): string {
const config = this._config as WiFiSourceConfig | undefined;
return config?.password || "";
}

get _is_hidden(): boolean {
const config = this._config as WiFiSourceConfig | undefined;
return config?.is_hidden || false;
}

get _entity(): string {
const config = this._config as EntitySourceConfig | undefined;
return config?.entity || ""
}

private _localize(ts: TranslatableString): string {
return localizeWithHass(ts, this.hass, this._config);
}

protected render(): TemplateResult | void {
if (!this.hass) {
return html``;
}

const entities = Object.keys(this.hass.states);

return html`
<div class="card-config">
<div class="values">
<paper-dropdown-menu
label=${this._localize("editor.label.source")}
@iron-select=${this._selectionChanged}
.configValue=${"source"}>
<paper-listbox
slot="dropdown-content"
attr-for-selected="value"
.selected=${this._source}>
${Object.values(SourceType).map(source => {
return html`<paper-item .value=${source}>${this._localize(`editor.options.source.${source}`)}</paper-item>`;
})}
</paper-listbox>
</paper-dropdown-menu>
</div>
${this._config?.source == SourceType.TEXT ? html`
<div class="values">
<paper-input
label=${this._localize("editor.label.text")}
.value=${this._text}
.configValue=${"text"}
@value-changed=${this._valueChanged}></paper-input>
</div>` : ""}
${this._config?.source == SourceType.WIFI ? html`
<div class="values">
<paper-dropdown-menu
label=${this._localize("editor.label.auth_type")}
@iron-select=${this._selectionChanged}
.configValue=${"auth_type"}>
<paper-listbox
slot="dropdown-content"
attr-for-selected="value"
.selected=${this._auth_type}>
${Object.values(AuthenticationType).map(auth_type => {
return html`<paper-item .value=${auth_type}>${this._localize(`editor.options.auth_type.${auth_type}`)}</paper-item>`;
})}
</paper-listbox>
</paper-dropdown-menu>
</div>
<div class="values">
<paper-input
label=${this._localize("editor.label.ssid")}
.value=${this._ssid}
.configValue=${"ssid"}
@value-changed=${this._valueChanged}></paper-input>
</div>
${this._auth_type != AuthenticationType.NOPASS ? html`
<div class="values">
<paper-input
label=${this._localize("editor.label.password")}
.value=${this._password}
.configValue=${"password"}
@value-changed=${this._valueChanged}></paper-input>
</div>
` : ""}
<div class="values">
<ha-formfield .label=${this._localize("editor.label.is_hidden")}>
<ha-switch
.checked=${this._is_hidden}
.configValue=${"is_hidden"}
@change=${this._valueChanged}></ha-switch>
</ha-formfield>
</div>
` : ""}
${this._config?.source == SourceType.ENTITY ? html`
<div class="values">
<paper-dropdown-menu
label=${this._localize("editor.label.entity")}
@value-changed=${this._valueChanged}
.configValue=${"entity"}>
<paper-listbox slot="dropdown-content" .selected=${entities.indexOf(this._entity)}>
${entities.map(entity => {
return html` <paper-item>${entity}</paper-item> `;
})}
</paper-listbox>
</paper-dropdown-menu>
</div>` : ""}
</div>
`;
}

private _initialize(): void {
if (this.hass === undefined) return;
if (this._config === undefined) return;
this._initialized = true;
}

private _selectionChanged(ev): void {
ev.stopPropagation();
this._updateConfig(ev.currentTarget.configValue, ev.detail.item.value);
}

private _valueChanged(ev): void {
ev.stopPropagation();
const value = ev.target.checked !== undefined ? ev.target.checked : ev.target.value;
this._updateConfig(ev.target.configValue, value);
}

private _updateConfig(key: string, value: any) {
if (!this._config || !this.hass) {
return;
}

if (this[`_${key}`] === value) {
return;
}

if (!key) {
const tmpConfig = { ...this._config };
delete tmpConfig[value];
this._config = tmpConfig;
} else {
this._config = {
...this._config,
[key]: value,
};
}
fireEvent(this, "config-changed", { config: this._config });
}

static get styles(): CSSResultGroup {
return css`
.values {
padding-left: 16px;
margin: 8px;
display: grid;
}
ha-formfield {
padding: 8px;
}
`;
}
}
Loading

0 comments on commit 0d5ed95

Please sign in to comment.