From 65ad109a6db366546eb4bd77736d7a040e0ef7be Mon Sep 17 00:00:00 2001
From: Amit <91756648+pathofleastresistor@users.noreply.github.com>
Date: Sat, 13 Jan 2024 11:57:35 -0800
Subject: [PATCH] Redesign the list layout (#12)
* first commit
* smaller list icon size
* Adjust browser nav button size
* first commit
* smaller list icon size
* Adjust browser nav button size
---
polr-ytube-media-card.js | 220 +++++++++++++++++--------
src/elements/polr-ytube-browser.ts | 4 +-
src/elements/polr-ytube-list-item.ts | 229 +++++++++++++++++++++++++++
src/elements/polr-ytube-list.ts | 198 +++--------------------
4 files changed, 410 insertions(+), 241 deletions(-)
create mode 100644 src/elements/polr-ytube-list-item.ts
diff --git a/polr-ytube-media-card.js b/polr-ytube-media-card.js
index 35c1c6b..faee57d 100644
--- a/polr-ytube-media-card.js
+++ b/polr-ytube-media-card.js
@@ -305,60 +305,64 @@ const VolumeOffIcon = x `
`;
-let PoLRYTubeList = class PoLRYTubeList extends s$1 {
- updated(_changedProperties) {
- // this.renderRoot.querySelector(".current")?.scrollIntoView({
- // behavior: "smooth",
- // block: "start",
- // inline: "center",
- // });
+let PoLRYTubeListItem = class PoLRYTubeListItem extends s$1 {
+ constructor() {
+ super(...arguments);
+ this._actions = [];
+ this._hasAdditionalActions = false;
}
- _is_current(element) {
- if (this.entity == null)
- return false;
- if (!isNumeric(element.media_content_id))
- return false;
- if ("current_track" in this.entity["attributes"]) {
- return (parseInt(element.media_content_id) - 1 ==
- this.entity["attributes"]["current_track"]);
- }
- return false;
+ firstUpdated(_changedProperties) {
+ if (this.element.can_expand)
+ this._primaryAction = "more";
+ else
+ this._primaryAction = "play";
+ this._hasAdditionalActions =
+ this.element.can_expand == this.element.can_play
+ ? this.element.can_expand
+ : this.element.media_content_type == "track";
+ this.requestUpdate();
}
render() {
- if (this.state == 4 /* PoLRYTubeListState.LOADING */) {
- return x `
Loading...
`;
- }
- if (this.state == 8 /* PoLRYTubeListState.NO_RESULTS */) {
- return x `
+ ${this._primaryAction != "more"
+ ? this._renderMoreButton(this.element)
+ : x ``}
+ ${this._primaryAction != "play"
+ ? this._renderPlayButton(this.element)
+ : x ``}
+ ${this._renderRadioButton(this.element)}
+
+ `
+ : ``}
+ `;
+ }
+ _performPrimaryAction() {
+ if (this._primaryAction == "more")
+ this._fireNavigateEvent(this.element);
+ if (this._primaryAction == "play")
+ this._play(this.element);
+ }
+ _renderAction() {
+ if (this._primaryAction == "more") {
+ return x `
+ return x `
`;
}
- return x `
`;
+ return x `
+
+ `;
}
async _fireNavigateEvent(element) {
this.dispatchEvent(new CustomEvent("navigate", {
@@ -441,25 +446,37 @@ let PoLRYTubeList = class PoLRYTubeList extends s$1 {
static get styles() {
return [
i$5 `
- .elements {
- }
-
- .element {
+ :host {
display: grid;
- grid-template-columns: 40px 1fr min-content;
+ grid-template-columns: 1fr min-content min-content;
align-items: center;
- gap: 12px;
- padding: 12px;
+ }
+
+ mwc-list-item {
border-radius: 12px;
}
+ svg {
+ width: 18px;
+ height: 18px;
+ fill: var(--primary-text-color);
+ }
+
+ .divider {
+ width: 2px;
+ background: rgba(var(--rgb-primary-text-color), 0.2);
+ height: 50%;
+ margin: 0 4px;
+ }
+
.actions {
display: grid;
- grid-template-columns: auto auto auto;
+ grid-template-columns: auto;
+ align-items: center;
}
.actions > mwc-button {
- margin-right: 8px;
+ margin: 0 8px;
}
.element img {
@@ -476,9 +493,80 @@ let PoLRYTubeList = class PoLRYTubeList extends s$1 {
align-items: center;
justify-content: center;
}
+ `,
+ ];
+ }
+};
+__decorate([
+ t$1()
+], PoLRYTubeListItem.prototype, "entity", void 0);
+__decorate([
+ t$1()
+], PoLRYTubeListItem.prototype, "hass", void 0);
+__decorate([
+ t$1()
+], PoLRYTubeListItem.prototype, "element", void 0);
+__decorate([
+ t$1()
+], PoLRYTubeListItem.prototype, "current", void 0);
+PoLRYTubeListItem = __decorate([
+ e$5("polr-ytube-list-item")
+], PoLRYTubeListItem);
- .current {
- background-color: var(--primary-background-color);
+let PoLRYTubeList = class PoLRYTubeList extends s$1 {
+ render() {
+ if (this.state == 4 /* PoLRYTubeListState.LOADING */) {
+ return x `
Loading...
`;
+ }
+ if (this.state == 8 /* PoLRYTubeListState.NO_RESULTS */) {
+ return x `
No results
`;
+ }
+ if (this.state == 16 /* PoLRYTubeListState.ERROR */) {
+ return x `
Unknown Error
`;
+ }
+ if (this.state == 2 /* PoLRYTubeListState.HAS_RESULTS */) {
+ if (this.elements.length == 0)
+ return x ``;
+ const renderedElements = this.elements.map((element) => {
+ return x `
+
this._fireNavigateEvent(ev.detail.action)}
+ >
+ `;
+ });
+ return x `${renderedElements}`;
+ }
+ }
+ _is_current(element) {
+ if (this.entity == null)
+ return false;
+ if (!isNumeric(element.media_content_id))
+ return false;
+ if ("current_track" in this.entity["attributes"]) {
+ return (parseInt(element.media_content_id) - 1 ==
+ this.entity["attributes"]["current_track"]);
+ }
+ return false;
+ }
+ async _fireNavigateEvent(element) {
+ this.dispatchEvent(new CustomEvent("navigate", {
+ detail: {
+ action: element,
+ },
+ }));
+ return;
+ }
+ static get styles() {
+ return [
+ i$5 `
+ :host {
+ display: grid;
+ gap: 4px;
+ --mdc-list-item-graphic-size: 40px;
}
.empty,
@@ -4552,8 +4640,8 @@ let PoLRYTubeBrowser = class PoLRYTubeBrowser extends s$1 {
align-items: center;
gap: 4px;
justify-content: flex-start;
- padding: 4px 0;
- --mdc-icon-button-size: 32px;
+ padding: 8px 0;
+ --mdc-icon-button-size: 30px;
--mdc-icon-size: 20px;
}
diff --git a/src/elements/polr-ytube-browser.ts b/src/elements/polr-ytube-browser.ts
index a88a5e8..4cfddcd 100644
--- a/src/elements/polr-ytube-browser.ts
+++ b/src/elements/polr-ytube-browser.ts
@@ -266,8 +266,8 @@ export class PoLRYTubeBrowser extends LitElement {
align-items: center;
gap: 4px;
justify-content: flex-start;
- padding: 4px 0;
- --mdc-icon-button-size: 32px;
+ padding: 8px 0;
+ --mdc-icon-button-size: 30px;
--mdc-icon-size: 20px;
}
diff --git a/src/elements/polr-ytube-list-item.ts b/src/elements/polr-ytube-list-item.ts
new file mode 100644
index 0000000..e7ba6d9
--- /dev/null
+++ b/src/elements/polr-ytube-list-item.ts
@@ -0,0 +1,229 @@
+import {
+ LitElement,
+ html,
+ css,
+ CSSResultGroup,
+ nothing,
+ PropertyValueMap,
+} from "lit";
+import { customElement, property, state } from "lit/decorators.js";
+import { PlayableMediaList, PoLRYTubeItem } from "../utils/utils";
+import { ForwardBurgerIcon, PlayIcon, RadioTowerIcon } from "../utils/icons";
+
+@customElement("polr-ytube-list-item")
+export class PoLRYTubeListItem extends LitElement {
+ @state() public entity: any;
+ @state() public hass: any;
+ @state() public element: PoLRYTubeItem;
+ @state() public current: boolean;
+ private _primaryAction: any;
+ private _actions: any[] = [];
+ private _hasAdditionalActions: boolean = false;
+
+ protected firstUpdated(
+ _changedProperties: PropertyValueMap
| Map
+ ): void {
+ if (this.element.can_expand) this._primaryAction = "more";
+ else this._primaryAction = "play";
+
+ this._hasAdditionalActions =
+ this.element.can_expand == this.element.can_play
+ ? this.element.can_expand
+ : this.element.media_content_type == "track";
+ this.requestUpdate();
+ }
+
+ render() {
+ return html`
+
+ ${this._renderThumbnail(this.element)} ${this.element.title}
+ ${this._renderAction()}
+
+ ${this._hasAdditionalActions
+ ? html`
+
+
+ ${this._primaryAction != "more"
+ ? this._renderMoreButton(this.element)
+ : html``}
+ ${this._primaryAction != "play"
+ ? this._renderPlayButton(this.element)
+ : html``}
+ ${this._renderRadioButton(this.element)}
+
+ `
+ : ``}
+ `;
+ }
+
+ private _performPrimaryAction() {
+ if (this._primaryAction == "more")
+ this._fireNavigateEvent(this.element);
+
+ if (this._primaryAction == "play") this._play(this.element);
+ }
+
+ private _renderAction() {
+ if (this._primaryAction == "more") {
+ return html`${ForwardBurgerIcon}`;
+ }
+
+ if (this._primaryAction == "play") {
+ return html``;
+ }
+
+ return html``;
+ }
+
+ private _renderMoreButton(element: PoLRYTubeItem) {
+ if (!element["can_expand"]) return html``;
+
+ return html`
+ this._fireNavigateEvent(element)}>
+ ${ForwardBurgerIcon}
+
+ `;
+ }
+
+ private _renderPlayButton(element: PoLRYTubeItem) {
+ if (!element.can_play) return html``;
+ return html`
+ this._play(element)}>
+ ${PlayIcon}
+
+ `;
+ }
+
+ private _renderRadioButton(element: PoLRYTubeItem) {
+ if (element.media_content_type == "track") {
+ const id =
+ element.media_content_type == "track"
+ ? element.media_content_id
+ : this.entity["attributes"]["videoId"];
+
+ return html`
+ this._startRadio(id)}>
+ ${RadioTowerIcon}
+
+ `;
+ }
+ return nothing;
+ }
+
+ private _renderThumbnail(element: PoLRYTubeItem) {
+ if (element.thumbnail == "") {
+ return html`
+
+
`;
+ }
+
+ return html`
+
+ `;
+ }
+
+ private async _fireNavigateEvent(element: PoLRYTubeItem) {
+ this.dispatchEvent(
+ new CustomEvent("navigate", {
+ detail: {
+ action: element,
+ },
+ })
+ );
+ return;
+ }
+
+ private async _startRadio(media_content_id) {
+ this.hass.callService("media_player", "shuffle_set", {
+ entity_id: this.entity["entity_id"],
+ shuffle: false,
+ });
+
+ this.hass.callService("media_player", "play_media", {
+ entity_id: this.entity["entity_id"],
+ media_content_id: media_content_id,
+ media_content_type: "vid_channel",
+ });
+ return;
+ }
+
+ private async _play(element: PoLRYTubeItem) {
+ if (element.media_content_type == "PLAYLIST_GOTO_TRACK") {
+ this.hass.callService("ytube_music_player", "call_method", {
+ entity_id: this.entity["entity_id"],
+ command: "goto_track",
+ parameters: element.media_content_id,
+ });
+
+ return;
+ }
+ if (PlayableMediaList.includes(element.media_class)) {
+ this.hass.callService("media_player", "play_media", {
+ entity_id: this.entity["entity_id"],
+ media_content_id: element.media_content_id,
+ media_content_type: element.media_content_type,
+ });
+
+ return;
+ }
+ }
+
+ static get styles(): CSSResultGroup {
+ return [
+ css`
+ :host {
+ display: grid;
+ grid-template-columns: 1fr min-content min-content;
+ align-items: center;
+ }
+
+ mwc-list-item {
+ border-radius: 12px;
+ }
+
+ svg {
+ width: 18px;
+ height: 18px;
+ fill: var(--primary-text-color);
+ }
+
+ .divider {
+ width: 2px;
+ background: rgba(var(--rgb-primary-text-color), 0.2);
+ height: 50%;
+ margin: 0 4px;
+ }
+
+ .actions {
+ display: grid;
+ grid-template-columns: auto;
+ align-items: center;
+ }
+
+ .actions > mwc-button {
+ margin: 0 8px;
+ }
+
+ .element img {
+ width: 40px;
+ height: 40px;
+ border-radius: 5%;
+ }
+
+ .empty-thumbnail {
+ display: flex;
+ background-color: rgba(111, 111, 111, 0.2);
+ border-radius: 5%;
+ height: 40px;
+ align-items: center;
+ justify-content: center;
+ }
+ `,
+ ];
+ }
+}
diff --git a/src/elements/polr-ytube-list.ts b/src/elements/polr-ytube-list.ts
index 5f8e452..da72d14 100644
--- a/src/elements/polr-ytube-list.ts
+++ b/src/elements/polr-ytube-list.ts
@@ -1,20 +1,7 @@
-import {
- LitElement,
- html,
- css,
- CSSResultGroup,
- nothing,
- PropertyValueMap,
-} from "lit";
-import { customElement, property, state } from "lit/decorators.js";
-import {
- isNumeric,
- PlayableMediaList,
- PoLRYTubeItem,
- PoLRYTubeListState,
- areDeeplyEqual,
-} from "../utils/utils";
-import { ForwardBurgerIcon, PlayIcon, RadioTowerIcon } from "../utils/icons";
+import { LitElement, html, css, CSSResultGroup } from "lit";
+import { customElement, state } from "lit/decorators.js";
+import { isNumeric, PoLRYTubeItem, PoLRYTubeListState } from "../utils/utils";
+import "./polr-ytube-list-item";
@customElement("polr-ytube-list")
export class PoLRYTubeList extends LitElement {
@@ -23,29 +10,6 @@ export class PoLRYTubeList extends LitElement {
@state() public elements: PoLRYTubeItem[];
@state() public state: PoLRYTubeListState;
- protected updated(
- _changedProperties: PropertyValueMap | Map
- ): void {
- // this.renderRoot.querySelector(".current")?.scrollIntoView({
- // behavior: "smooth",
- // block: "start",
- // inline: "center",
- // });
- }
-
- private _is_current(element: PoLRYTubeItem): boolean {
- if (this.entity == null) return false;
- if (!isNumeric(element.media_content_id)) return false;
-
- if ("current_track" in this.entity["attributes"]) {
- return (
- parseInt(element.media_content_id) - 1 ==
- this.entity["attributes"]["current_track"]
- );
- }
- return false;
- }
-
render() {
if (this.state == PoLRYTubeListState.LOADING) {
return html`Loading...
`;
@@ -64,75 +28,32 @@ export class PoLRYTubeList extends LitElement {
const renderedElements = this.elements.map((element) => {
return html`
-
- ${this._renderThumbnail(element)}
-
${element.title}
-
- ${this._renderMoreButton(element)}
- ${this._renderRadioButton(element)}
- ${this._renderPlayButton(element)}
-
-
+
+ this._fireNavigateEvent(ev.detail.action)}
+ >
`;
});
- return html`
-
- `;
+ return html`${renderedElements}`;
}
}
- private _renderMoreButton(element: PoLRYTubeItem) {
- if (!element["can_expand"]) return html``;
-
- return html`
- this._fireNavigateEvent(element)}>
- ${ForwardBurgerIcon}
-
- `;
- }
-
- private _renderPlayButton(element: PoLRYTubeItem) {
- if (!element.can_play) return html``;
- return html`
- this._play(element)}>
- ${PlayIcon}
-
- `;
- }
-
- private _renderRadioButton(element: PoLRYTubeItem) {
- if (
- this._is_current(element) ||
- element.media_content_type == "track"
- ) {
- const id =
- element.media_content_type == "track"
- ? element.media_content_id
- : this.entity["attributes"]["videoId"];
-
- return html`
- this._startRadio(id)}>
- ${RadioTowerIcon}
-
- `;
- }
- return nothing;
- }
+ private _is_current(element: PoLRYTubeItem): boolean {
+ if (this.entity == null) return false;
+ if (!isNumeric(element.media_content_id)) return false;
- private _renderThumbnail(element: PoLRYTubeItem) {
- if (element.thumbnail == "") {
- return html`
-
-
`;
+ if ("current_track" in this.entity["attributes"]) {
+ return (
+ parseInt(element.media_content_id) - 1 ==
+ this.entity["attributes"]["current_track"]
+ );
}
-
- return html` `;
+ return false;
}
private async _fireNavigateEvent(element: PoLRYTubeItem) {
@@ -146,82 +67,13 @@ export class PoLRYTubeList extends LitElement {
return;
}
- private async _startRadio(media_content_id) {
- this.hass.callService("media_player", "shuffle_set", {
- entity_id: this.entity["entity_id"],
- shuffle: false,
- });
-
- this.hass.callService("media_player", "play_media", {
- entity_id: this.entity["entity_id"],
- media_content_id: media_content_id,
- media_content_type: "vid_channel",
- });
- return;
- }
-
- private async _play(element: PoLRYTubeItem) {
- if (element.media_content_type == "PLAYLIST_GOTO_TRACK") {
- this.hass.callService("ytube_music_player", "call_method", {
- entity_id: this.entity["entity_id"],
- command: "goto_track",
- parameters: element.media_content_id,
- });
-
- return;
- }
- if (PlayableMediaList.includes(element.media_class)) {
- this.hass.callService("media_player", "play_media", {
- entity_id: this.entity["entity_id"],
- media_content_id: element.media_content_id,
- media_content_type: element.media_content_type,
- });
-
- return;
- }
- }
-
static get styles(): CSSResultGroup {
return [
css`
- .elements {
- }
-
- .element {
- display: grid;
- grid-template-columns: 40px 1fr min-content;
- align-items: center;
- gap: 12px;
- padding: 12px;
- border-radius: 12px;
- }
-
- .actions {
+ :host {
display: grid;
- grid-template-columns: auto auto auto;
- }
-
- .actions > mwc-button {
- margin-right: 8px;
- }
-
- .element img {
- width: 40px;
- height: 40px;
- border-radius: 5%;
- }
-
- .empty-thumbnail {
- display: flex;
- background-color: rgba(111, 111, 111, 0.2);
- border-radius: 5%;
- height: 40px;
- align-items: center;
- justify-content: center;
- }
-
- .current {
- background-color: var(--primary-background-color);
+ gap: 4px;
+ --mdc-list-item-graphic-size: 40px;
}
.empty,