From 95dfcaef9933f9bd6a11bee7e0c3b7f1d9b92386 Mon Sep 17 00:00:00 2001 From: Johan Frick Date: Sun, 4 Feb 2024 16:56:30 +0100 Subject: [PATCH] fix: improve grouping performance --- src/card.ts | 8 ++-- src/components/group.ts | 13 +++--- src/sections/grouping.ts | 91 ++++++++++++++++------------------------ 3 files changed, 47 insertions(+), 65 deletions(-) diff --git a/src/card.ts b/src/card.ts index 4a581261..a5ecf0b7 100644 --- a/src/card.ts +++ b/src/card.ts @@ -27,11 +27,6 @@ export class Card extends LitElement { render() { this.createStore(); - - if (cardDoesNotContainAllSections(this.config)) { - window.addEventListener(ACTIVE_PLAYER_EVENT, this.activePlayerListener); - } - let height = getHeight(this.config); const sections = this.config.sections; const showFooter = !sections || sections.length > 1; @@ -112,6 +107,9 @@ export class Card extends LitElement { connectedCallback() { super.connectedCallback(); + if (cardDoesNotContainAllSections(this.config)) { + window.addEventListener(ACTIVE_PLAYER_EVENT, this.activePlayerListener); + } window.addEventListener(CALL_MEDIA_STARTED, this.callMediaStartedListener); window.addEventListener(CALL_MEDIA_DONE, this.callMediaDoneListener); } diff --git a/src/components/group.ts b/src/components/group.ts index d817d8f2..0f492c60 100755 --- a/src/components/group.ts +++ b/src/components/group.ts @@ -2,28 +2,24 @@ import { css, html, LitElement } from 'lit'; import { property } from 'lit/decorators.js'; import { when } from 'lit/directives/when.js'; import Store from '../model/store'; -import { CardConfig } from '../types'; import { dispatchActivePlayerId, getSpeakerList } from '../utils/utils'; import { MediaPlayer } from '../model/media-player'; class Group extends LitElement { @property({ attribute: false }) store!: Store; - private config!: CardConfig; @property({ attribute: false }) player!: MediaPlayer; @property({ type: Boolean }) selected = false; dispatchEntityIdEvent = () => { if (this.selected) { const entityId = this.player.id; - dispatchActivePlayerId(entityId, this.config, this); + dispatchActivePlayerId(entityId, this.store.config, this); } }; render() { - this.config = this.store.config; - const currentTrack = this.config.hideGroupCurrentTrack ? '' : this.player.getCurrentTrack(); + const currentTrack = this.store.config.hideGroupCurrentTrack ? '' : this.player.getCurrentTrack(); const speakerList = getSpeakerList(this.player, this.store.predefinedGroups); - this.dispatchEntityIdEvent(); const icon = this.player.attributes.icon; return html` player.id); - this.groupingItems = this.getGroupingItems(); - this.originalGroupingItems = this.getGroupingItems(); - this.notJoinedPlayers = this.getNotJoinedPlayers(); - this.joinedPlayers = this.getJoinedPlayers(); - } + this.activePlayer = this.store.activePlayer; + this.allGroups = this.store.allGroups; + this.mediaControlService = this.store.mediaControlService; + this.mediaPlayerIds = this.store.allMediaPlayers.map((player) => player.id); + this.groupingItems = this.getGroupingItems(); + this.notJoinedPlayers = this.getNotJoinedPlayers(); + this.joinedPlayers = this.getJoinedPlayers(); return html`
@@ -40,7 +37,7 @@ export class Grouping extends LitElement {
${this.groupingItems.map((item) => { return html` -
+
- + Apply Cancel @@ -148,24 +145,16 @@ export class Grouping extends LitElement { ]; } - async itemClick(item: GroupingItem) { - if (!item.isDisabled) { - item.toggle(); - const selectedItems = this.groupingItems.filter((item) => { - item.isDisabled = false; - return item.isSelected; - }); - if (selectedItems.length === 1) { - selectedItems[0].isDisabled = true; - } - this.requestUpdate(); + itemClick(item: GroupingItem) { + if (item.isDisabled) { + return; + } + if (this.modifiedItems.includes(item.player.id)) { + this.modifiedItems = this.modifiedItems.filter((id) => id !== item.player.id); + } else { + this.modifiedItems = [...this.modifiedItems, item.player.id]; } } - - private isGroupingModified() { - return JSON.stringify(this.groupingItems) === JSON.stringify(this.originalGroupingItems); - } - async applyGrouping() { const isSelected = this.groupingItems.filter((item) => item.isSelected); const unjoin = this.groupingItems @@ -187,7 +176,7 @@ export class Grouping extends LitElement { if (join.length > 0) { await this.mediaControlService.join(main, join); } - this.groupingItems = this.originalGroupingItems = []; + this.modifiedItems = []; } private cancelGrouping() { @@ -195,7 +184,15 @@ export class Grouping extends LitElement { } private getGroupingItems() { - return this.store.allMediaPlayers.map((player) => new GroupingItem(player, this.activePlayer)); + const groupingItems = this.store.allMediaPlayers.map( + (player) => new GroupingItem(player, this.activePlayer, this.modifiedItems.includes(player.id)), + ); + const selectedItems = groupingItems.filter((item) => item.isSelected); + if (selectedItems.length === 1) { + selectedItems[0].isDisabled = true; + } + + return groupingItems; } private renderJoinAllButton() { @@ -228,7 +225,7 @@ export class Grouping extends LitElement { private getJoinedPlayers() { return this.mediaPlayerIds.filter( - (playerId) => playerId !== this.activePlayer.id && this.activePlayer.hasMember(playerId), + (playerId) => playerId === this.activePlayer.id || this.activePlayer.hasMember(playerId), ); } @@ -237,7 +234,7 @@ export class Grouping extends LitElement { return html` { - this.groupingItems = this.originalGroupingItems = []; + this.modifiedItems = []; await this.mediaControlService.createGroup(predefinedGroup, this.allGroups, this.store.config, this); }} .icon=${'mdi:speaker-multiple'} @@ -251,33 +248,19 @@ export class Grouping extends LitElement { class GroupingItem { isSelected: boolean; icon!: string; - isDisabled: boolean; + isDisabled = false; + isModified: boolean; readonly name: string; readonly isMain: boolean; readonly player: MediaPlayer; - readonly originalState: boolean; - constructor(player: MediaPlayer, activePlayer: MediaPlayer) { + constructor(player: MediaPlayer, activePlayer: MediaPlayer, isModified: boolean) { this.isMain = player.id === activePlayer.id; - this.isSelected = this.isMain || activePlayer.hasMember(player.id); - this.originalState = this.isSelected; + this.isModified = isModified; + const currentlyJoined = this.isMain || activePlayer.hasMember(player.id); + this.isSelected = isModified ? !currentlyJoined : currentlyJoined; this.player = player; - - this.isDisabled = this.isSelected && !activePlayer.isGrouped(); this.name = player.name; - this.updateIcon(); - } - - toggle() { - this.isSelected = !this.isSelected; - this.updateIcon(); - } - - isModified() { - return this.isSelected !== this.originalState; - } - - private updateIcon() { this.icon = this.isSelected ? 'check-circle' : 'checkbox-blank-circle-outline'; } }