From 62117e69659368ac8def98920acd5dde186ba7d6 Mon Sep 17 00:00:00 2001 From: jtbgroup Date: Tue, 19 Dec 2023 21:30:09 +0100 Subject: [PATCH 1/6] 1.2.0 --- changelog.md | 9 ++ package.json | 4 +- src/const.ts | 2 +- src/kodi-musicbrainz-card.ts | 264 ++++++++++++++++++++++------------- 4 files changed, 180 insertions(+), 99 deletions(-) diff --git a/changelog.md b/changelog.md index 80c4956..e6317bc 100755 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,14 @@ # Changelog +## 1.2.0 + +- filters for the album types + +## 1.1.4 + +- Code cleanup +- Handle some errors + ## 1.1.3 - bug in the layout diff --git a/package.json b/package.json index f8f837c..0b69550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kodi-musicbrainz-card", - "version": "1.1.3", + "version": "1.2.0", "description": "Kodi MusicBrainz Card", "keywords": [ "home-assistant", @@ -15,6 +15,7 @@ "author": "Gautier Vanderslyen ", "license": "MIT", "dependencies": { + "@material/mwc-checkbox": "^0.3.6", "change-perspective": "^1.0.1", "compare-versions": "^4.0.1", "custom-card-helpers": "^1.9.0", @@ -52,4 +53,3 @@ "rollup": "rollup -c" } } - diff --git a/src/const.ts b/src/const.ts index 7e6266a..cf9f0b6 100644 --- a/src/const.ts +++ b/src/const.ts @@ -1,4 +1,4 @@ -export const CARD_VERSION = "1.1.3"; +export const CARD_VERSION = "1.2.0"; export const DEFAULT_ENTITY_NAME = "sensor.kodi_media_sensor_playlist"; export const RESULT_ARTISTS = 1; diff --git a/src/kodi-musicbrainz-card.ts b/src/kodi-musicbrainz-card.ts index 4ff6367..dd440e3 100644 --- a/src/kodi-musicbrainz-card.ts +++ b/src/kodi-musicbrainz-card.ts @@ -1,15 +1,16 @@ +import "@material/mwc-checkbox"; /* eslint-disable @typescript-eslint/no-explicit-any */ -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { HomeAssistant, LovelaceCardEditor, getLovelace } from "custom-card-helpers"; +import { css, CSSResultGroup, html, LitElement, TemplateResult, PropertyValues } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { HomeAssistant, LovelaceCardEditor, getLovelace, hasConfigOrEntityChanged } from "custom-card-helpers"; import { localize } from "./localize/localize"; // import Sortable from "sortablejs"; // import { loadSortable } from "./sortable.ondemand"; // import type { SortableEvent } from "sortablejs"; - import "./editor"; import type { KodiMusicBrainzCardConfig } from "./types"; -import { CARD_VERSION, DEFAULT_ENTITY_NAME} from "./const"; +import { CARD_VERSION, DEFAULT_ENTITY_NAME } from "./const"; +import { Checkbox } from "@material/mwc-checkbox"; console.info( `%c KODI-MUSICBRAINZ-CARD\n%c ${localize("common.version")} ${CARD_VERSION} `, @@ -42,16 +43,15 @@ export class KodiMusicBrainzCard extends LitElement { private _entity; private _card; private _searchInput; - private _artS; - private _firstRun = true; + private _mediaPlayerInput; + private _alreadyRunned = false; private _runCounter = 0; + @state() private config!: KodiMusicBrainzCardConfig; // TODO Add any properities that should cause your element to re-render here // https://lit.dev/docs/components/properties/ @property({ attribute: false }) public hass!: HomeAssistant; - @state() private config!: KodiMusicBrainzCardConfig; - public setConfig(config: KodiMusicBrainzCardConfig): void { // TODO Check for required fields and that they are of the proper format if (!config) { @@ -63,21 +63,31 @@ export class KodiMusicBrainzCard extends LitElement { } this.config = config; + this._alreadyRunned = false; } public getCardSize(): number { return 1; } + // https://lit.dev/docs/components/lifecycle/#reactive-update-cycle-performing + protected shouldUpdate(changedProps: PropertyValues): boolean { + if (!this.config || !this.config.entity) { + return false; + } + + return hasConfigOrEntityChanged(this, changedProps, false); + } + // https://lit.dev/docs/components/rendering/ protected render(): TemplateResult | void { let errorMessage; let searchTxt = null; - if( this._searchInput ){ - searchTxt= this._searchInput.value; + if (this._searchInput) { + searchTxt = this._searchInput.value; } - if (this._firstRun) { + if (!this._alreadyRunned) { this._card = html` ${errorMessage ? errorMessage : this._buildCardContainer()} `; + this._alreadyRunned = true; } - - if( searchTxt ){ + + if (searchTxt) { this._searchInput.value = searchTxt; } - if (this.config.entity && !this._firstRun) { - this.fillEntityArtist(this.config.entity); + if (this.config.entity && this._alreadyRunned) { + this.fillMediaPlayerArtist(this.config.entity); } return this._card; } - private fillEntityArtist(entity) { + private fillMediaPlayerArtist(entity) { const entityState = this.hass.states[entity]; - const artistEl = this.shadowRoot?.querySelector("#entity_artist") as HTMLElement; const btnEl = document.getElementById("search_artist_btn"); if (entityState["attributes"]["media_artist"]) { const artist = entityState["attributes"]["media_artist"]; - artistEl.setAttribute("value", artist); - artistEl.setAttribute("label", "Currently playing in entity"); + this._mediaPlayerInput.setAttribute("value", artist); + this._mediaPlayerInput.setAttribute("label", "Currently playing in entity"); btnEl?.setAttribute("enabled", ""); } else { - artistEl.setAttribute("value", ""); - artistEl.setAttribute("label", "No artist playing"); + this._mediaPlayerInput.setAttribute("value", ""); + this._mediaPlayerInput.setAttribute("label", "No artist playing"); btnEl?.setAttribute("disabled", ""); } } @@ -122,14 +132,14 @@ export class KodiMusicBrainzCard extends LitElement { this._searchInput.setAttribute("class", "form-button"); this._searchInput.addEventListener("keydown", event => { if (event.code === "Enter") { - this._searchArtists(); + this._searchFromInput(); } }); return html`
${this.config.show_version ? html`
${CARD_VERSION}
` : ""} - ${this.config.entity ? this._createLinkEntity() : html``} + ${this.config.entity ? this._createMediaPlayerElements() : html``}
${this._searchInput}
@@ -137,58 +147,72 @@ export class KodiMusicBrainzCard extends LitElement { class="form-button" label="Search" raised - @click="${this._searchArtists}" + @click="${this._searchFromInput}" }>
+
+
+ Live +
+
+ Compilation +
+
+ Remix +
+
+ Soundtrack +
+
`; } - private _createLinkEntity() { + private _createMediaPlayerElements() { const entity = this.config.entity; let entityState; - const haTxt = document.createElement("ha-textfield"); - haTxt.id = "entity_artist"; - haTxt.className = "rounded"; - haTxt.setAttribute("disabled", ""); - this._artS = haTxt; + this._mediaPlayerInput = document.createElement("ha-textfield"); + this._mediaPlayerInput.id = "entity_artist"; + this._mediaPlayerInput.className = "rounded"; + this._mediaPlayerInput.setAttribute("disabled", ""); const searchBtn = document.createElement("mwc-button"); searchBtn.id = "search_artist_btn"; searchBtn.className = "form-button"; searchBtn.setAttribute("raised", ""); searchBtn.setAttribute("Label", "search"); - searchBtn.addEventListener("click", event => { - console.debug(event.target); - this._searchWithEntity(); - }); + // searchBtn.addEventListener("click", event => { + // // console.debug(event.target); + // this._searchWithEntity(); + // }); + + searchBtn.addEventListener("click", this._searchFromMediaPlayer.bind(this)); if (entity) { entityState = this.hass.states[entity]; } if (entityState["attributes"]["media_artist"]) { - haTxt.setAttribute("Label", "Currently playing"); - haTxt.setAttribute("value", entityState["attributes"]["media_artist"]); + this._mediaPlayerInput.setAttribute("Label", "Currently playing"); + this._mediaPlayerInput.setAttribute("value", entityState["attributes"]["media_artist"]); searchBtn.setAttribute("enabled", ""); } else { - haTxt.setAttribute("Label", "No artist playing"); - haTxt.setAttribute("value", ""); + this._mediaPlayerInput.setAttribute("Label", "No artist playing"); + this._mediaPlayerInput.setAttribute("value", ""); searchBtn.setAttribute("disabled", ""); } - - return html`
${haTxt}${searchBtn}
`; + return html`
${this._mediaPlayerInput}${searchBtn}
`; } - private _createReleaseGroups(releaseGroups) { + private _createReleaseGroupsList(releaseGroups) { const a = releaseGroups.sort(function (a, b) { const type = a["primary-type"].localeCompare(b["primary-type"]); if (type != 0) return type; @@ -220,42 +244,59 @@ export class KodiMusicBrainzCard extends LitElement { resultDiv.append(primaryTypesDiv); this._filterTypes(a, item).map(res => { - const titleDiv = document.createElement("div"); - titleDiv.className = "mb_rg_detail_title"; - titleDiv.innerHTML = res["title"]; - - const releaseIcon = document.createElement("ha-icon"); - releaseIcon.setAttribute("icon", "mdi:calendar"); - const releaseDiv = document.createElement("div"); - releaseDiv.className = "mb_rg_detail_release"; - releaseDiv.append(releaseIcon); - releaseDiv.innerHTML = res["first-release-date"] ? res["first-release-date"] : ""; - - const detailTypesIcon = document.createElement("ha-icon"); - detailTypesIcon.setAttribute("icon", "mdi:shape-outline"); - const detailTypesDiv = document.createElement("div"); - detailTypesDiv.className = "mb_rg_detail_types"; - detailTypesDiv.append(detailTypesIcon); - detailTypesDiv.innerHTML = res["secondary-types"] ? res["secondary-types"] : ""; - - const imgCoverIcon = document.createElement("ha-icon"); - imgCoverIcon.id = "covericon_" + res["id"]; - imgCoverIcon.setAttribute("icon", "mdi:disc"); - const coverDiv = document.createElement("div"); - coverDiv.id = "coverdiv_" + res["id"]; - coverDiv.className = "mb_rg_detail_cover"; - coverDiv.append(imgCoverIcon); - - this.getCover(res); - - const detailGrid = document.createElement("div"); - detailGrid.className = "mb_rg_grid_detail"; - detailGrid.append(titleDiv); - detailGrid.append(releaseDiv); - detailGrid.append(detailTypesDiv); - detailGrid.append(coverDiv); - - containerDiv.append(detailGrid); + let secondaryType = res["secondary-types"] ? res["secondary-types"] : ""; + secondaryType = secondaryType.toString(); + let addItem = true; + if (secondaryType.toLowerCase().includes("live") && !this.isFilterLiveSelected()) { + addItem = false; + } else if (secondaryType.toLowerCase().includes("compilation") && !this.isFilterCompilationSelected()) { + addItem = false; + } else if (secondaryType.toLowerCase().includes("remix") && !this.isFilterRemixSelected()) { + addItem = false; + } else if (secondaryType.toLowerCase().includes("soundtrack") && !this.isFilterSoundtrackSelected()) { + addItem = false; + } else if (secondaryType.toLowerCase().includes("album") || secondaryType == "") { + addItem = true; + } + + if (addItem) { + const titleDiv = document.createElement("div"); + titleDiv.className = "mb_rg_detail_title"; + titleDiv.innerHTML = res["title"]; + + const releaseIcon = document.createElement("ha-icon"); + releaseIcon.setAttribute("icon", "mdi:calendar"); + const releaseDiv = document.createElement("div"); + releaseDiv.className = "mb_rg_detail_release"; + releaseDiv.append(releaseIcon); + releaseDiv.innerHTML = res["first-release-date"] ? res["first-release-date"] : ""; + + const detailTypesIcon = document.createElement("ha-icon"); + detailTypesIcon.setAttribute("icon", "mdi:shape-outline"); + const detailTypesDiv = document.createElement("div"); + detailTypesDiv.className = "mb_rg_detail_types"; + detailTypesDiv.append(detailTypesIcon); + detailTypesDiv.innerHTML = res["secondary-types"] ? res["secondary-types"] : ""; + + const imgCoverIcon = document.createElement("ha-icon"); + imgCoverIcon.id = "covericon_" + res["id"]; + imgCoverIcon.setAttribute("icon", "mdi:disc"); + const coverDiv = document.createElement("div"); + coverDiv.id = "coverdiv_" + res["id"]; + coverDiv.className = "mb_rg_detail_cover"; + coverDiv.append(imgCoverIcon); + + this.getCover(res); + + const detailGrid = document.createElement("div"); + detailGrid.className = "mb_rg_grid_detail"; + detailGrid.append(titleDiv); + detailGrid.append(releaseDiv); + detailGrid.append(detailTypesDiv); + detailGrid.append(coverDiv); + + containerDiv.append(detailGrid); + } }); }); @@ -301,7 +342,7 @@ export class KodiMusicBrainzCard extends LitElement { return result; } - private _createArtistsResult(artists) { + private _createArtistsList(artists) { const artistsDiv = document.createElement("div"); artistsDiv.id = "result"; artistsDiv.className = "mb_results"; @@ -343,15 +384,12 @@ export class KodiMusicBrainzCard extends LitElement { return artistsDiv; } - private _searchWithEntity() { - const artistEl = this.shadowRoot?.querySelector("#entity_artist") as HTMLElement; - const t = artistEl.getAttribute("value"); - - this._searchInput.value = t; - this._searchArtists(); + private _searchFromMediaPlayer() { + this._searchInput.value = this._mediaPlayerInput.value; + this._searchFromInput(); } - private _searchArtists() { + private _searchFromInput() { const searchText = this._searchInput.value; let url = "https://musicbrainz.org/ws/2/artist/?fmt=json&query=artist:" + searchText; @@ -360,15 +398,35 @@ export class KodiMusicBrainzCard extends LitElement { fetch(url) .then(response => response.json()) .then(data => { - this.fillArtists(data.artists); + this.fillArtistsList(data.artists); }); } + private isFilterLiveSelected() { + const a = this.shadowRoot?.querySelector("#filter_live") as Checkbox; + return a.checked; + } + + private isFilterCompilationSelected() { + const a = this.shadowRoot?.querySelector("#filter_compilation") as Checkbox; + return a.checked; + } + + private isFilterRemixSelected() { + const a = this.shadowRoot?.querySelector("#filter_remix") as Checkbox; + return a.checked; + } + + private isFilterSoundtrackSelected() { + const a = this.shadowRoot?.querySelector("#filter_soundtrack") as Checkbox; + return a.checked; + } + private getResultElement() { return this.shadowRoot?.querySelector("#result-musicbrainz") as HTMLElement; } - private _clearResult() { + private _clearResultList() { const divMB = this.getResultElement(); const divresult = this.shadowRoot?.querySelector("#result") as HTMLElement; if (divresult) { @@ -376,14 +434,14 @@ export class KodiMusicBrainzCard extends LitElement { } } - private fillArtists(artists) { - this._clearResult(); - this.getResultElement().append(this._createArtistsResult(artists)); + private fillArtistsList(artists) { + this._clearResultList(); + this.getResultElement().append(this._createArtistsList(artists)); } - private fillResultGroups(resultGroups) { - this._clearResult(); - this.getResultElement().append(this._createReleaseGroups(resultGroups)); + private fillReleaseGroupsList(resultGroups) { + this._clearResultList(); + this.getResultElement().append(this._createReleaseGroupsList(resultGroups)); } private searchReleaseGroups(artistId) { @@ -407,7 +465,7 @@ export class KodiMusicBrainzCard extends LitElement { tmp = tmp.concat(element["release-groups"]); }); - this.fillResultGroups(tmp); + this.fillReleaseGroupsList(tmp); }) .catch(function (error) { // if there's an error, log it @@ -548,6 +606,20 @@ export class KodiMusicBrainzCard extends LitElement { grid-template-rows: auto; gap: 5px; } + + .mb_form_filter { + display: grid; + grid-template-columns: auto auto; + grid-template-rows: auto; + align-items: center; + } + + .mb_form_filters { + grid-column: 1 / 3; + grid-row: 2; + display: flex; + gap: 3px; + } `; } } From 3439a372bc8eaa2a8deda23381b3f328646d8b48 Mon Sep 17 00:00:00 2001 From: jtbgroup Date: Wed, 20 Dec 2023 07:41:58 +0100 Subject: [PATCH 2/6] configs filters --- src/editor.ts | 44 ++++++++++++++++++++++++++++++++++++ src/kodi-musicbrainz-card.ts | 36 +++++++++++++++++++---------- src/types.ts | 4 ++++ 3 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/editor.ts b/src/editor.ts index e741b57..63a55c4 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -36,6 +36,18 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar get _show_version(): boolean { return this._config?.show_version || false; } + get _filter_secondType_live(): boolean { + return this._config?.filter_secondType_live || false; + } + get _filter_secondType_compilation(): boolean { + return this._config?.filter_secondType_compilation || false; + } + get _filter_secondType_remix(): boolean { + return this._config?.filter_secondType_remix || false; + } + get _filter_secondType_soundtrack(): boolean { + return this._config?.filter_secondType_soundtrack || false; + } protected render(): TemplateResult | void { if (!this.hass || !this._helpers) { @@ -79,6 +91,38 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar @change=${this._valueChanged}> +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
`; } diff --git a/src/kodi-musicbrainz-card.ts b/src/kodi-musicbrainz-card.ts index dd440e3..116b702 100644 --- a/src/kodi-musicbrainz-card.ts +++ b/src/kodi-musicbrainz-card.ts @@ -125,7 +125,27 @@ export class KodiMusicBrainzCard extends LitElement { } } + private createFilterEl(id, configCheck) { + const el = document.createElement("mwc-checkbox"); + el.setAttribute("id", id); + if (configCheck) { + el.setAttribute("checked", ""); + } + return el; + } + private _buildCardContainer() { + const _filter_live_el = this.createFilterEl("filter_live", this.config.filter_secondType_live); + const _filter_compilation_el = this.createFilterEl( + "filter_compilation", + this.config.filter_secondType_compilation, + ); + const _filter_soundtrack_el = this.createFilterEl( + "filter_soundtrack", + this.config.filter_secondType_soundtrack, + ); + const _filter_remix_el = this.createFilterEl("filter_remix", this.config.filter_secondType_remix); + this._searchInput = document.createElement("ha-textfield"); this._searchInput.setAttribute("outlined", ""); this._searchInput.setAttribute("label", "Search criteria"); @@ -157,18 +177,10 @@ export class KodiMusicBrainzCard extends LitElement { }>
-
- Live -
-
- Compilation -
-
- Remix -
-
- Soundtrack -
+
${_filter_live_el}Live
+
${_filter_compilation_el}Compilation
+
${_filter_remix_el}Remix
+
${_filter_soundtrack_el}Soundtrack
diff --git a/src/types.ts b/src/types.ts index fc1a851..0dbbcc9 100755 --- a/src/types.ts +++ b/src/types.ts @@ -12,5 +12,9 @@ export interface KodiMusicBrainzCardConfig extends LovelaceCardConfig { entity?: string; title?: string; show_version: boolean; + filter_secondType_live: boolean; + filter_secondType_soundtrack: boolean; + filter_secondType_compilation: boolean; + filter_secondType_remix: boolean; } From bbcf4cca5b39b5f879bc935e2cdb1f63b7006a40 Mon Sep 17 00:00:00 2001 From: jtbgroup Date: Wed, 20 Dec 2023 18:20:01 +0100 Subject: [PATCH 3/6] filter applied in the query --- src/editor.ts | 66 ++++++++++---- src/kodi-musicbrainz-card.ts | 165 +++++++++++++++++++---------------- src/types.ts | 9 +- 3 files changed, 142 insertions(+), 98 deletions(-) diff --git a/src/editor.ts b/src/editor.ts index 63a55c4..6ec688d 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -36,19 +36,29 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar get _show_version(): boolean { return this._config?.show_version || false; } - get _filter_secondType_live(): boolean { + + get _filter_primaryType_album(): boolean { + return this._config?.filter_primaryType_album || false; + } + get _filter_primaryType_single(): boolean { + return this._config?.filter_primaryType_single || false; + } + + get _filter_secondaryType_live(): boolean { return this._config?.filter_secondType_live || false; } - get _filter_secondType_compilation(): boolean { - return this._config?.filter_secondType_compilation || false; + get _filter_secondaryType_compilation(): boolean { + return this._config?.filter_secondaryType_compilation || false; } - get _filter_secondType_remix(): boolean { - return this._config?.filter_secondType_remix || false; + get _filter_secondaryType_remix(): boolean { + return this._config?.filter_secondaryType_remix || false; } - get _filter_secondType_soundtrack(): boolean { - return this._config?.filter_secondType_soundtrack || false; + get _filter_secondaryType_soundtrack(): boolean { + return this._config?.filter_secondaryType_soundtrack || false; } + + protected render(): TemplateResult | void { if (!this.hass || !this._helpers) { return html``; @@ -91,35 +101,53 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar @change=${this._valueChanged}> + +
+ + + +
+
+ + + +
+
- +
- +
- +
- +
diff --git a/src/kodi-musicbrainz-card.ts b/src/kodi-musicbrainz-card.ts index 116b702..889b711 100644 --- a/src/kodi-musicbrainz-card.ts +++ b/src/kodi-musicbrainz-card.ts @@ -38,14 +38,10 @@ export class KodiMusicBrainzCard extends LitElement { }; } - private _entityState; - private _json_meta; - private _entity; private _card; private _searchInput; private _mediaPlayerInput; private _alreadyRunned = false; - private _runCounter = 0; @state() private config!: KodiMusicBrainzCardConfig; // TODO Add any properities that should cause your element to re-render here @@ -135,16 +131,19 @@ export class KodiMusicBrainzCard extends LitElement { } private _buildCardContainer() { - const _filter_live_el = this.createFilterEl("filter_live", this.config.filter_secondType_live); + const _filter_prim_single_el = this.createFilterEl("filter_primary_single", this.config.filter_primaryType_single); + const _filter_prim_album_el = this.createFilterEl("filter_primary_album", this.config.filter_primaryType_album); + + const _filter_live_el = this.createFilterEl("filter_secondary_live", this.config.filter_secondType_live); const _filter_compilation_el = this.createFilterEl( - "filter_compilation", - this.config.filter_secondType_compilation, + "filter_secondary_compilation", + this.config.filter_secondaryType_compilation, ); const _filter_soundtrack_el = this.createFilterEl( - "filter_soundtrack", - this.config.filter_secondType_soundtrack, + "filter_secondary_soundtrack", + this.config.filter_secondaryType_soundtrack, ); - const _filter_remix_el = this.createFilterEl("filter_remix", this.config.filter_secondType_remix); + const _filter_remix_el = this.createFilterEl("filter_secondary_remix", this.config.filter_secondaryType_remix); this._searchInput = document.createElement("ha-textfield"); this._searchInput.setAttribute("outlined", ""); @@ -176,7 +175,11 @@ export class KodiMusicBrainzCard extends LitElement { @click="${this._clearResultList}" }> -
+
+
${_filter_prim_album_el}Album
+
${_filter_prim_single_el}Single
+
+
${_filter_live_el}Live
${_filter_compilation_el}Compilation
${_filter_remix_el}Remix
@@ -256,59 +259,42 @@ export class KodiMusicBrainzCard extends LitElement { resultDiv.append(primaryTypesDiv); this._filterTypes(a, item).map(res => { - let secondaryType = res["secondary-types"] ? res["secondary-types"] : ""; - secondaryType = secondaryType.toString(); - let addItem = true; - if (secondaryType.toLowerCase().includes("live") && !this.isFilterLiveSelected()) { - addItem = false; - } else if (secondaryType.toLowerCase().includes("compilation") && !this.isFilterCompilationSelected()) { - addItem = false; - } else if (secondaryType.toLowerCase().includes("remix") && !this.isFilterRemixSelected()) { - addItem = false; - } else if (secondaryType.toLowerCase().includes("soundtrack") && !this.isFilterSoundtrackSelected()) { - addItem = false; - } else if (secondaryType.toLowerCase().includes("album") || secondaryType == "") { - addItem = true; - } - - if (addItem) { - const titleDiv = document.createElement("div"); - titleDiv.className = "mb_rg_detail_title"; - titleDiv.innerHTML = res["title"]; - - const releaseIcon = document.createElement("ha-icon"); - releaseIcon.setAttribute("icon", "mdi:calendar"); - const releaseDiv = document.createElement("div"); - releaseDiv.className = "mb_rg_detail_release"; - releaseDiv.append(releaseIcon); - releaseDiv.innerHTML = res["first-release-date"] ? res["first-release-date"] : ""; - - const detailTypesIcon = document.createElement("ha-icon"); - detailTypesIcon.setAttribute("icon", "mdi:shape-outline"); - const detailTypesDiv = document.createElement("div"); - detailTypesDiv.className = "mb_rg_detail_types"; - detailTypesDiv.append(detailTypesIcon); - detailTypesDiv.innerHTML = res["secondary-types"] ? res["secondary-types"] : ""; - - const imgCoverIcon = document.createElement("ha-icon"); - imgCoverIcon.id = "covericon_" + res["id"]; - imgCoverIcon.setAttribute("icon", "mdi:disc"); - const coverDiv = document.createElement("div"); - coverDiv.id = "coverdiv_" + res["id"]; - coverDiv.className = "mb_rg_detail_cover"; - coverDiv.append(imgCoverIcon); - - this.getCover(res); - - const detailGrid = document.createElement("div"); - detailGrid.className = "mb_rg_grid_detail"; - detailGrid.append(titleDiv); - detailGrid.append(releaseDiv); - detailGrid.append(detailTypesDiv); - detailGrid.append(coverDiv); - - containerDiv.append(detailGrid); - } + const titleDiv = document.createElement("div"); + titleDiv.className = "mb_rg_detail_title"; + titleDiv.innerHTML = res["title"]; + + const releaseIcon = document.createElement("ha-icon"); + releaseIcon.setAttribute("icon", "mdi:calendar"); + const releaseDiv = document.createElement("div"); + releaseDiv.className = "mb_rg_detail_release"; + releaseDiv.append(releaseIcon); + releaseDiv.innerHTML = res["first-release-date"] ? res["first-release-date"] : ""; + + const detailTypesIcon = document.createElement("ha-icon"); + detailTypesIcon.setAttribute("icon", "mdi:shape-outline"); + const detailTypesDiv = document.createElement("div"); + detailTypesDiv.className = "mb_rg_detail_types"; + detailTypesDiv.append(detailTypesIcon); + detailTypesDiv.innerHTML = res["secondary-types"] ? res["secondary-types"] : ""; + + const imgCoverIcon = document.createElement("ha-icon"); + imgCoverIcon.id = "covericon_" + res["id"]; + imgCoverIcon.setAttribute("icon", "mdi:disc"); + const coverDiv = document.createElement("div"); + coverDiv.id = "coverdiv_" + res["id"]; + coverDiv.className = "mb_rg_detail_cover"; + coverDiv.append(imgCoverIcon); + + this.getCover(res); + + const detailGrid = document.createElement("div"); + detailGrid.className = "mb_rg_grid_detail"; + detailGrid.append(titleDiv); + detailGrid.append(releaseDiv); + detailGrid.append(detailTypesDiv); + detailGrid.append(coverDiv); + + containerDiv.append(detailGrid); }); }); @@ -414,23 +400,34 @@ export class KodiMusicBrainzCard extends LitElement { }); } - private isFilterLiveSelected() { - const a = this.shadowRoot?.querySelector("#filter_live") as Checkbox; + private isFilterPrimaryAlbumSelected() { + const a = this.shadowRoot?.querySelector("#filter_primary_album") as Checkbox; + return a.checked; + } + + private isFilterPrimarySingleSelected() { + const a = this.shadowRoot?.querySelector("#filter_primary_single") as Checkbox; + return a.checked; + } + + + private isFilterSecondaryLiveSelected() { + const a = this.shadowRoot?.querySelector("#filter_secondary_live") as Checkbox; return a.checked; } - private isFilterCompilationSelected() { - const a = this.shadowRoot?.querySelector("#filter_compilation") as Checkbox; + private isFilterSecondaryCompilationSelected() { + const a = this.shadowRoot?.querySelector("#filter_secondary_compilation") as Checkbox; return a.checked; } - private isFilterRemixSelected() { - const a = this.shadowRoot?.querySelector("#filter_remix") as Checkbox; + private isFilterSecondaryRemixSelected() { + const a = this.shadowRoot?.querySelector("#filter_secondary_remix") as Checkbox; return a.checked; } - private isFilterSoundtrackSelected() { - const a = this.shadowRoot?.querySelector("#filter_soundtrack") as Checkbox; + private isFilterSecondarySoundtrackSelected() { + const a = this.shadowRoot?.querySelector("#filter_secondary_soundtrack") as Checkbox; return a.checked; } @@ -457,10 +454,21 @@ export class KodiMusicBrainzCard extends LitElement { } private searchReleaseGroups(artistId) { + let typeFilter = !this.isFilterPrimaryAlbumSelected() ? " AND NOT primarytype:Album" : ""; + typeFilter += !this.isFilterPrimarySingleSelected() ? " AND NOT primarytype:Single" : ""; + typeFilter += !this.isFilterSecondaryLiveSelected() ? " AND NOT secondarytype:Live" : ""; + typeFilter += !this.isFilterSecondaryCompilationSelected() ? " AND NOT secondarytype:Compilation" : ""; + typeFilter += !this.isFilterSecondaryRemixSelected() ? " AND NOT secondarytype:Remix" : ""; + typeFilter += !this.isFilterSecondarySoundtrackSelected() ? " AND NOT secondarytype:Soundtrack" : ""; + const urlSingles = - "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=primarytype:single AND arid:" + artistId; + "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=primarytype:single AND arid:" + + artistId + + typeFilter; const urlAlbums = - "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=primarytype:album AND arid:" + artistId; + "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=primarytype:album AND arid:" + + artistId + + typeFilter; Promise.all([fetch(encodeURI(urlSingles)), fetch(encodeURI(urlAlbums))]) .then(function (responses) { @@ -626,12 +634,19 @@ export class KodiMusicBrainzCard extends LitElement { align-items: center; } - .mb_form_filters { + .mb_form_filters_primary { grid-column: 1 / 3; grid-row: 2; display: flex; gap: 3px; } + + .mb_form_filters_secondary { + grid-column: 1 / 3; + grid-row: 3; + display: flex; + gap: 3px; + } `; } } diff --git a/src/types.ts b/src/types.ts index 0dbbcc9..d40b5f9 100755 --- a/src/types.ts +++ b/src/types.ts @@ -12,9 +12,10 @@ export interface KodiMusicBrainzCardConfig extends LovelaceCardConfig { entity?: string; title?: string; show_version: boolean; - filter_secondType_live: boolean; - filter_secondType_soundtrack: boolean; - filter_secondType_compilation: boolean; - filter_secondType_remix: boolean; + filter_primaryType_single: boolean; + filter_primaryType_album: boolean; + filter_secondaryType_soundtrack: boolean; + filter_secondaryType_compilation: boolean; + filter_secondaryType_remix: boolean; } From 58b24935313c40142e269fbcf8531bddfe5e6bb0 Mon Sep 17 00:00:00 2001 From: jtbgroup Date: Wed, 20 Dec 2023 18:20:59 +0100 Subject: [PATCH 4/6] filter applied in the query --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index e6317bc..135c5fe 100755 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,7 @@ ## 1.2.0 -- filters for the album types +- filters for the album types applied before the query (primary and secondary types) ## 1.1.4 From 5735a5e32362f946125c39bc016cd2b0f4170d31 Mon Sep 17 00:00:00 2001 From: jtbgroup Date: Wed, 20 Dec 2023 18:23:18 +0100 Subject: [PATCH 5/6] filter applied in the query --- src/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.ts b/src/types.ts index d40b5f9..3f0f237 100755 --- a/src/types.ts +++ b/src/types.ts @@ -14,6 +14,7 @@ export interface KodiMusicBrainzCardConfig extends LovelaceCardConfig { show_version: boolean; filter_primaryType_single: boolean; filter_primaryType_album: boolean; + filter_secondaryType_live: boolean; filter_secondaryType_soundtrack: boolean; filter_secondaryType_compilation: boolean; filter_secondaryType_remix: boolean; From 43cd70682fa30c5f220e6f6e9020951c93e233d5 Mon Sep 17 00:00:00 2001 From: jtbgroup Date: Fri, 22 Dec 2023 07:08:38 +0100 Subject: [PATCH 6/6] working ok --- src/const.ts | 15 +++ src/editor.ts | 102 ++++++++------------ src/kodi-musicbrainz-card.ts | 175 ++++++++++++++++++----------------- src/types.ts | 7 ++ 4 files changed, 148 insertions(+), 151 deletions(-) diff --git a/src/const.ts b/src/const.ts index cf9f0b6..d7ee47c 100644 --- a/src/const.ts +++ b/src/const.ts @@ -4,3 +4,18 @@ export const DEFAULT_ENTITY_NAME = "sensor.kodi_media_sensor_playlist"; export const RESULT_ARTISTS = 1; export const RESULT_RELEASEGROUPS = 2; +export const PRIMARYY_TYPES = { + Album: { id: "filter_primaryType_album", editor_label: "Include primary type Album", mb_query:"album"}, + Single: { id: "filter_primaryType_single", editor_label: "Include primary type Single", mb_query:"single" }, + Broadcast: { id: "filter_primaryType_broadcast", editor_label: "Include primary type Broadcast" , mb_query:"broadcast"}, + EP: { id: "filter_primaryType_ep", editor_label: "Include primary type EP", mb_query:"ep" }, + Other: { id: "filter_primaryType_other", editor_label: "Include primary type Other" , mb_query:"dj-mix"}, +}; +export const SECONDARY_TYPES = { + Demo: { id: "filter_secondaryType_demo", editor_label: "Include secondary type Demo", mb_query:"demo" }, + Live: { id: "filter_secondaryType_live", editor_label: "Include secondary type Live", mb_query:"live" }, + Soundtrack: { id: "filter_secondaryType_soundtrack", editor_label: "Include secondary type Soundtrack", mb_query:"soundtrack" }, + Compilation: { id: "filter_secondaryType_compilation", editor_label: "Include secondary type Compilation", mb_query:"compilation" }, + Remix: { id: "filter_secondaryType_remix", editor_label: "Include secondary type Remix" , mb_query:"remix"}, + DJ_Mix: { id: "filter_secondaryType_djmix", editor_label: "Include secondary type DJ-Mix" , mb_query:"dj-mix"}, +}; diff --git a/src/editor.ts b/src/editor.ts index 6ec688d..aae66cf 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -3,6 +3,8 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent, HomeAssistant, LovelaceCardEditor } from "custom-card-helpers"; +import { PRIMARYY_TYPES, SECONDARY_TYPES } from "./const"; + import { KodiMusicBrainzCardConfig } from "./types"; @customElement("kodi-musicbrainz-card-editor") @@ -36,7 +38,7 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar get _show_version(): boolean { return this._config?.show_version || false; } - + get _filter_primaryType_album(): boolean { return this._config?.filter_primaryType_album || false; } @@ -44,21 +46,6 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar return this._config?.filter_primaryType_single || false; } - get _filter_secondaryType_live(): boolean { - return this._config?.filter_secondType_live || false; - } - get _filter_secondaryType_compilation(): boolean { - return this._config?.filter_secondaryType_compilation || false; - } - get _filter_secondaryType_remix(): boolean { - return this._config?.filter_secondaryType_remix || false; - } - get _filter_secondaryType_soundtrack(): boolean { - return this._config?.filter_secondaryType_soundtrack || false; - } - - - protected render(): TemplateResult | void { if (!this.hass || !this._helpers) { return html``; @@ -102,59 +89,43 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar
-
- - - -
-
- - - -
- -
- - - -
-
- - - -
-
- - - -
-
- - - -
+ ${this.createPrimaryTypesEl()} + ${this.createSecondaryTypesEl()}
`; } + private createTypeEl(typeValue){ + const selected = this._config?.[typeValue.id]; + selected == undefined ? false : selected; + + return html`
+ +
` + } + + private createSecondaryTypesEl() { + const itemTemplates: TemplateResult[] = []; + for (const key of Object.keys(SECONDARY_TYPES)) { + itemTemplates.push(this.createTypeEl(SECONDARY_TYPES[key])); + } + return itemTemplates; + } + + + private createPrimaryTypesEl() { + const itemTemplates: TemplateResult[] = []; + for (const key of Object.keys(PRIMARYY_TYPES)) { + itemTemplates.push(this.createTypeEl(PRIMARYY_TYPES[key])); + } + return itemTemplates; + } + private _initialize(): void { if (this.hass === undefined) return; if (this._config === undefined) return; @@ -167,6 +138,7 @@ export class KodiMusicBrainzCardEditor extends LitElement implements LovelaceCar } private _valueChanged(ev): void { + console.debug(this._config); if (!this._config || !this.hass) { return; } diff --git a/src/kodi-musicbrainz-card.ts b/src/kodi-musicbrainz-card.ts index 889b711..6fb313f 100644 --- a/src/kodi-musicbrainz-card.ts +++ b/src/kodi-musicbrainz-card.ts @@ -9,7 +9,7 @@ import { localize } from "./localize/localize"; // import type { SortableEvent } from "sortablejs"; import "./editor"; import type { KodiMusicBrainzCardConfig } from "./types"; -import { CARD_VERSION, DEFAULT_ENTITY_NAME } from "./const"; +import { CARD_VERSION, DEFAULT_ENTITY_NAME, PRIMARYY_TYPES, SECONDARY_TYPES } from "./const"; import { Checkbox } from "@material/mwc-checkbox"; console.info( @@ -121,29 +121,12 @@ export class KodiMusicBrainzCard extends LitElement { } } - private createFilterEl(id, configCheck) { - const el = document.createElement("mwc-checkbox"); - el.setAttribute("id", id); - if (configCheck) { - el.setAttribute("checked", ""); - } - return el; - } - private _buildCardContainer() { - const _filter_prim_single_el = this.createFilterEl("filter_primary_single", this.config.filter_primaryType_single); - const _filter_prim_album_el = this.createFilterEl("filter_primary_album", this.config.filter_primaryType_album); - - const _filter_live_el = this.createFilterEl("filter_secondary_live", this.config.filter_secondType_live); - const _filter_compilation_el = this.createFilterEl( - "filter_secondary_compilation", - this.config.filter_secondaryType_compilation, - ); - const _filter_soundtrack_el = this.createFilterEl( - "filter_secondary_soundtrack", - this.config.filter_secondaryType_soundtrack, - ); - const _filter_remix_el = this.createFilterEl("filter_secondary_remix", this.config.filter_secondaryType_remix); + // const _filter_prim_single_el = this.createFilterEl( + // "filter_primary_single", + // this.config.filter_primaryType_single, + // ); + // const _filter_prim_album_el = this.createFilterEl("filter_primary_album", this.config.filter_primaryType_album); this._searchInput = document.createElement("ha-textfield"); this._searchInput.setAttribute("outlined", ""); @@ -175,22 +158,50 @@ export class KodiMusicBrainzCard extends LitElement { @click="${this._clearResultList}" }> -
-
${_filter_prim_album_el}Album
-
${_filter_prim_single_el}Single
-
-
-
${_filter_live_el}Live
-
${_filter_compilation_el}Compilation
-
${_filter_remix_el}Remix
-
${_filter_soundtrack_el}Soundtrack
+
+
Primary Type
+
${this.createPrimaryTypesEl()}
+
Secondary Type
+
${this.createSecondaryTypesEl()}
+
-
`; } + private createTypeEl(key, typeValue) { + let selected = this.config[typeValue.id]; + selected = selected == undefined ? false : selected; + return html`
+ ${key} +
`; + } + private createPrimaryTypesEl() { + const itemTemplates: TemplateResult[] = []; + for (const key of Object.keys(PRIMARYY_TYPES)) { + itemTemplates.push(this.createTypeEl(key, PRIMARYY_TYPES[key])); + } + return itemTemplates; + } + + private createSecondaryTypesEl() { + const itemTemplates: TemplateResult[] = []; + for (const key of Object.keys(SECONDARY_TYPES)) { + itemTemplates.push(this.createTypeEl(key, SECONDARY_TYPES[key])); + } + return itemTemplates; + } + + private createFilterEl(id, configCheck) { + const el = document.createElement("mwc-checkbox"); + el.setAttribute("id", id); + if (configCheck) { + el.setAttribute("checked", ""); + } + return el; + } + private _createMediaPlayerElements() { const entity = this.config.entity; let entityState; @@ -400,37 +411,6 @@ export class KodiMusicBrainzCard extends LitElement { }); } - private isFilterPrimaryAlbumSelected() { - const a = this.shadowRoot?.querySelector("#filter_primary_album") as Checkbox; - return a.checked; - } - - private isFilterPrimarySingleSelected() { - const a = this.shadowRoot?.querySelector("#filter_primary_single") as Checkbox; - return a.checked; - } - - - private isFilterSecondaryLiveSelected() { - const a = this.shadowRoot?.querySelector("#filter_secondary_live") as Checkbox; - return a.checked; - } - - private isFilterSecondaryCompilationSelected() { - const a = this.shadowRoot?.querySelector("#filter_secondary_compilation") as Checkbox; - return a.checked; - } - - private isFilterSecondaryRemixSelected() { - const a = this.shadowRoot?.querySelector("#filter_secondary_remix") as Checkbox; - return a.checked; - } - - private isFilterSecondarySoundtrackSelected() { - const a = this.shadowRoot?.querySelector("#filter_secondary_soundtrack") as Checkbox; - return a.checked; - } - private getResultElement() { return this.shadowRoot?.querySelector("#result-musicbrainz") as HTMLElement; } @@ -454,23 +434,33 @@ export class KodiMusicBrainzCard extends LitElement { } private searchReleaseGroups(artistId) { - let typeFilter = !this.isFilterPrimaryAlbumSelected() ? " AND NOT primarytype:Album" : ""; - typeFilter += !this.isFilterPrimarySingleSelected() ? " AND NOT primarytype:Single" : ""; - typeFilter += !this.isFilterSecondaryLiveSelected() ? " AND NOT secondarytype:Live" : ""; - typeFilter += !this.isFilterSecondaryCompilationSelected() ? " AND NOT secondarytype:Compilation" : ""; - typeFilter += !this.isFilterSecondaryRemixSelected() ? " AND NOT secondarytype:Remix" : ""; - typeFilter += !this.isFilterSecondarySoundtrackSelected() ? " AND NOT secondarytype:Soundtrack" : ""; - - const urlSingles = - "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=primarytype:single AND arid:" + - artistId + - typeFilter; - const urlAlbums = - "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=primarytype:album AND arid:" + - artistId + - typeFilter; - - Promise.all([fetch(encodeURI(urlSingles)), fetch(encodeURI(urlAlbums))]) + let typeFilter = ""; + for (const key of Object.keys(SECONDARY_TYPES)) { + const typeSelected = this.shadowRoot?.querySelector("#" + SECONDARY_TYPES[key].id) as Checkbox; + typeFilter += typeSelected.checked ? "" : " AND NOT secondarytype:" + SECONDARY_TYPES[key].mb_query; + } + + const queryURL: string[] = []; + for (const key of Object.keys(PRIMARYY_TYPES)) { + const typeSelected = this.shadowRoot?.querySelector("#" + PRIMARYY_TYPES[key].id) as Checkbox; + if (typeSelected.checked) { + queryURL.push( + "https://musicbrainz.org/ws/2/release-group/?fmt=json&query=arid:" + + artistId + + " AND primarytype:" + + PRIMARYY_TYPES[key].mb_query + + typeFilter, + ); + } + } + + console.debug(queryURL); + const fetched: Promise[] = []; + for (const url of queryURL) { + fetched.push(fetch(encodeURI(url))); + } + + Promise.all(fetched) .then(function (responses) { // Get a JSON object from each of the responses return Promise.all( @@ -627,26 +617,39 @@ export class KodiMusicBrainzCard extends LitElement { gap: 5px; } - .mb_form_filter { + .mb_form_filters { + display: grid; + grid-template-columns: auto; + grid-template-rows: auto; + align-items: center; + grid-column: 1 / 3; + } + + .mb_form_filter_type{ display: grid; grid-template-columns: auto auto; grid-template-rows: auto; align-items: center; } + .mb_form_filters_title_primary, .mb_form_filters_title_secondary{ + font-weight: bold; + } + .mb_form_filters_primary { - grid-column: 1 / 3; - grid-row: 2; display: flex; gap: 3px; } .mb_form_filters_secondary { - grid-column: 1 / 3; - grid-row: 3; display: flex; + flex-wrap: wrap; gap: 3px; } + + #result-musicbrainz{ + grid-column: 1 / 3; + } `; } } diff --git a/src/types.ts b/src/types.ts index 3f0f237..8fccb2f 100755 --- a/src/types.ts +++ b/src/types.ts @@ -14,9 +14,16 @@ export interface KodiMusicBrainzCardConfig extends LovelaceCardConfig { show_version: boolean; filter_primaryType_single: boolean; filter_primaryType_album: boolean; + filter_primaryType_ep: boolean; + filter_primaryType_broadcast: boolean; + filter_primaryType_other: boolean; + filter_secondaryType_demo: boolean; filter_secondaryType_live: boolean; filter_secondaryType_soundtrack: boolean; filter_secondaryType_compilation: boolean; filter_secondaryType_remix: boolean; + filter_secondaryType_djmix: boolean; + limit: number; } +