Skip to content

Commit

Permalink
Add my link support (#606)
Browse files Browse the repository at this point in the history
* Add my link support

* Update src/main.ts
  • Loading branch information
ludeeus authored Jul 7, 2022
1 parent 7781dce commit 6173dd6
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/components/dialogs/hacs-custom-repositories-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ export class HacsCustomRepositoriesDialog extends HacsDialogBase {
<span slot="description">${repo.full_name} (${repo.category})</span>
<mwc-icon-button
@click=${(ev) => {
ev.stopPropagation();
@click=${(ev: Event) => {
ev.preventDefault();
this._removeRepository(String(repo.id));
}}
>
Expand Down
100 changes: 100 additions & 0 deletions src/hacs-my-redirect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { navigate } from "../homeassistant-frontend/src/common/navigate";
import {
createSearchParam,
extractSearchParamsObject,
} from "../homeassistant-frontend/src/common/url/search-params";
import "../homeassistant-frontend/src/layouts/hass-error-screen";
import {
ParamType,
Redirect,
Redirects,
} from "../homeassistant-frontend/src/panels/my/ha-panel-my";
import { HomeAssistant, Route } from "../homeassistant-frontend/src/types";
import { Hacs } from "./data/hacs";

export const REDIRECTS: Redirects = {
hacs_repository: {
redirect: "/hacs/repository",
params: {
owner: "string",
repository: "string",
category: "string?",
},
},
};

@customElement("hacs-my-redirect")
class HacsMyRedirect extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false }) public hacs!: Hacs;

@property({ attribute: false }) public route!: Route;

@state() private _error?: TemplateResult | string;

protected firstUpdated(_changedProperties): void {
const dividerPos = this.route.path.indexOf("/", 1);
const path = this.route.path.substr(dividerPos + 1);
const redirect = REDIRECTS[path];

if (!redirect) {
this._error = this.hacs.localize("my.not_supported", {
link: html`<a
target="_blank"
rel="noreferrer noopener"
href="https://my.home-assistant.io/faq.html#supported-pages"
>
${this.hacs.localize("my.faq_link")}
</a>`,
});
return;
}

let url: string;
try {
url = this._createRedirectUrl(redirect);
} catch (err: any) {
this._error = this.hacs.localize("my.error");
return;
}

navigate(url, { replace: true });
}

protected render(): TemplateResult {
if (this._error) {
return html`<hass-error-screen .error=${this._error}></hass-error-screen>`;
}
return html``;
}

private _createRedirectUrl(redirect: Redirect): string {
const params = this._createRedirectParams(redirect);
return `${redirect.redirect}${params}`;
}

private _createRedirectParams(redirect: Redirect): string {
const params = extractSearchParamsObject();
if (!redirect.params && !Object.keys(params).length) {
return "";
}
const resultParams = {};
for (const [key, type] of Object.entries(redirect.params || {})) {
if (!params[key] && type.endsWith("?")) {
continue;
}
if (!params[key] || !this._checkParamType(type, params[key])) {
throw Error();
}
resultParams[key] = params[key];
}
return `?${createSearchParam(resultParams)}`;
}

private _checkParamType(type: ParamType, _value: string) {
return type === "string" || type === "string?";
}
}
5 changes: 5 additions & 0 deletions src/hacs-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ class HacsRouter extends HassRouterPage {

protected routerOptions: RouterOptions = {
defaultPage: "entry",
showLoading: true,
routes: {
_my_redirect: {
tag: "hacs-my-redirect",
load: () => import("./hacs-my-redirect"),
},
entry: {
tag: "hacs-entry-panel",
load: () => import("./panels/hacs-entry-panel"),
Expand Down
11 changes: 10 additions & 1 deletion src/localize/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@
},
"pending_repository_upgrade": "You are running version {downloaded}, version {available} is available"
},
"my": {
"not_supported": "This redirect is not supported. Check the {link} for the supported redirects and the version they where introduced.",
"documentation": "documentation",
"faq_link": "My Home Assistant FAQ",
"error": "An unknown error occurred",
"repository_not_found": "Repository {repository} not found",
"add_repository_title": "Add custom repository",
"add_repository_description": "This will add the custom repository '{repository}' to be tracked by HACS, do you want to add it?"
},
"store": {
"explore": "Explore & download repositories",
"new_repositories_note": "There are some new repositories showing here",
Expand Down Expand Up @@ -222,4 +231,4 @@
"information": "Information",
"pending_updates": "Pending updates"
}
}
}
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class HacsFrontend extends HacsElement {
// Ignore if modifier keys are pressed
return;
}
if (["c", "m", "e"].includes(ev.key)) {
if (["c", "e"].includes(ev.key)) {
// @ts-ignore
fireEvent(mainWindow, "hass-quick-bar-trigger", ev, {
bubbles: false,
Expand Down
85 changes: 76 additions & 9 deletions src/panels/hacs-repository-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { mainWindow } from "../../homeassistant-frontend/src/common/dom/get_main_window";
import { navigate } from "../../homeassistant-frontend/src/common/navigate";
import { extractSearchParamsObject } from "../../homeassistant-frontend/src/common/url/search-params";
import "../../homeassistant-frontend/src/components/ha-fab";
import "../../homeassistant-frontend/src/components/ha-icon-overflow-menu";
import { getConfigEntries } from "../../homeassistant-frontend/src/data/config_entries";
Expand All @@ -31,8 +32,13 @@ import { HomeAssistant, Route } from "../../homeassistant-frontend/src/types";
import "../components/hacs-filter";
import "../components/hacs-repository-card";
import { Hacs } from "../data/hacs";
import { fetchRepositoryInformation, RepositoryInfo } from "../data/repository";
import { repositoryUninstall, repositoryUpdate } from "../data/websocket";
import { fetchRepositoryInformation, RepositoryBase, RepositoryInfo } from "../data/repository";
import {
getRepositories,
repositoryAdd,
repositoryUninstall,
repositoryUpdate,
} from "../data/websocket";
import { HacsStyles } from "../styles/hacs-common-style";
import { markdown } from "../tools/markdown/markdown";

Expand All @@ -52,15 +58,76 @@ export class HacsRepositoryPanel extends LitElement {

@state() private _error?: string;

protected firstUpdated(changedProperties: PropertyValues): void {
protected async firstUpdated(changedProperties: PropertyValues): Promise<void> {
super.firstUpdated(changedProperties);
const dividerPos = this.route.path.indexOf("/", 1);
const repositoryId = this.route.path.substr(dividerPos + 1);
if (!repositoryId) {
this._error = "Missing repositoryId from route";
return;
document.body.addEventListener("keydown", (ev: KeyboardEvent) => {
if (ev.ctrlKey || ev.shiftKey || ev.metaKey || ev.altKey) {
// Ignore if modifier keys are pressed
return;
}
if (["m"].includes(ev.key)) {
const myParams = new URLSearchParams({
redirect: "hacs_repository",
owner: this._repository!.full_name.split("/")[0],
repository: this._repository!.full_name.split("/")[0],
category: this._repository!.category,
});
window.open(`https://my.home-assistant.io/create-link/?${myParams.toString()}`, "_blank");
}
});

const params = extractSearchParamsObject();
if (Object.entries(params).length) {
let existing: RepositoryBase | undefined;
const requestedRepository = `${params.owner}/${params.repository}`;
existing = this.hacs.repositories.find(
(repository) =>
repository.full_name.toLocaleLowerCase() === requestedRepository.toLocaleLowerCase()
);
if (!existing && params.category) {
if (
!(await showConfirmationDialog(this, {
title: this.hacs.localize("my.add_repository_title"),
text: this.hacs.localize("my.add_repository_description", {
repository: requestedRepository,
}),
confirmText: this.hacs.localize("common.add"),
dismissText: this.hacs.localize("common.cancel"),
}))
) {
this._error = this.hacs.localize("my.repository_not_found", {
repository: requestedRepository,
});
return;
}
try {
await repositoryAdd(this.hass, requestedRepository, params.category);
this.hacs.repositories = await getRepositories(this.hass);
existing = this.hacs.repositories.find(
(repository) =>
repository.full_name.toLocaleLowerCase() === requestedRepository.toLocaleLowerCase()
);
} catch (err: any) {
this._error = err;
return;
}
}
if (existing) {
this._fetchRepository(String(existing.id));
} else {
this._error = this.hacs.localize("my.repository_not_found", {
repository: requestedRepository,
});
}
} else {
const dividerPos = this.route.path.indexOf("/", 1);
const repositoryId = this.route.path.substr(dividerPos + 1);
if (!repositoryId) {
this._error = "Missing repositoryId from route";
return;
}
this._fetchRepository(repositoryId);
}
this._fetchRepository(repositoryId);
}

protected updated(changedProps) {
Expand Down

0 comments on commit 6173dd6

Please sign in to comment.