Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add QR code to long lived access tokens dialog #8948

Merged
merged 3 commits into from Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
115 changes: 115 additions & 0 deletions src/panels/profile/ha-long-lived-access-token-dialog.ts
@@ -0,0 +1,115 @@
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
TemplateResult,
} from "lit-element";
import "@material/mwc-button";
import "@polymer/paper-input/paper-input";
import { fireEvent } from "../../common/dom/fire_event";
import { createCloseHeading } from "../../components/ha-dialog";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
import { LongLivedAccessTokenDialogParams } from "./show-long-lived-access-token-dialog";

const QR_LOGO_URL = "/static/icons/favicon-192x192.png";

@customElement("ha-long-lived-access-token-dialog")
export class HaLongLivedAccessTokenDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false })
private _params?: LongLivedAccessTokenDialogParams;

@internalProperty() private _qrCode?: TemplateResult;

public showDialog(params: LongLivedAccessTokenDialogParams): void {
this._params = params;
}

public closeDialog() {
this._params = undefined;
this._qrCode = undefined;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}

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

return html`
<ha-dialog
open
hideActions
.heading=${createCloseHeading(this.hass, this._params.name)}
@closed=${this.closeDialog}
>
<div>
<paper-input
dialogInitialFocus
.value=${this._params.token}
.label=${this.hass.localize(
"ui.panel.profile.long_lived_access_tokens.prompt_copy_token"
)}
type="text"
></paper-input>
<div id="qr">
${this._qrCode
? this._qrCode
: html`
<mwc-button @click=${this._generateQR}>
Generate QR code
</mwc-button>
`}
</div>
</div>
</ha-dialog>
`;
}

private async _generateQR() {
const qrcode = await import("qrcode");
const canvas = await qrcode.toCanvas(this._params?.token, {
width: 180,
errorCorrectionLevel: "Q",
});
const context = canvas.getContext("2d");

const imageObj = new Image();
imageObj.src = QR_LOGO_URL;
await new Promise((resolve) => {
imageObj.onload = resolve;
});
context.drawImage(
imageObj,
canvas.width / 3,
canvas.height / 3,
canvas.width / 3,
canvas.height / 3
);

this._qrCode = html`<img src=${canvas.toDataURL()}></img>`;
}

static get styles(): CSSResult[] {
return [
haStyleDialog,
css`
#qr {
text-align: center;
}
`,
];
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-long-lived-access-token-dialog": HaLongLivedAccessTokenDialog;
}
}
9 changes: 2 additions & 7 deletions src/panels/profile/ha-long-lived-access-tokens-card.ts
Expand Up @@ -25,6 +25,7 @@ import {
import { haStyle } from "../../resources/styles";
import "../../styles/polymer-ha-style";
import { HomeAssistant } from "../../types";
import { showLongLivedAccessTokenDialog } from "./show-long-lived-access-token-dialog";

@customElement("ha-long-lived-access-tokens-card")
class HaLongLivedTokens extends LitElement {
Expand Down Expand Up @@ -125,13 +126,7 @@ class HaLongLivedTokens extends LitElement {
client_name: name,
});

showPromptDialog(this, {
title: name,
text: this.hass.localize(
"ui.panel.profile.long_lived_access_tokens.prompt_copy_token"
),
defaultValue: token,
});
showLongLivedAccessTokenDialog(this, { token, name });

fireEvent(this, "hass-refresh-tokens");
} catch (err) {
Expand Down
17 changes: 17 additions & 0 deletions src/panels/profile/show-long-lived-access-token-dialog.ts
@@ -0,0 +1,17 @@
import { fireEvent } from "../../common/dom/fire_event";

export interface LongLivedAccessTokenDialogParams {
token: string;
name: string;
}

export const showLongLivedAccessTokenDialog = (
element: HTMLElement,
longLivedAccessTokenDialogParams: LongLivedAccessTokenDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "ha-long-lived-access-token-dialog",
dialogImport: () => import("./ha-long-lived-access-token-dialog"),
dialogParams: longLivedAccessTokenDialogParams,
});
};