Skip to content

Commit

Permalink
feature: make it possible to group favorites by type (folder)
Browse files Browse the repository at this point in the history
  • Loading branch information
punxaphil committed Jan 9, 2025
1 parent 5e96b3d commit 8d6b1df
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ numberOfFavoritesToShow: 10 # Use this to limit the amount of favorites to show
hideBrowseMediaButton: true # default is false. Hides the button to open the media browser.
replaceHttpWithHttpsForThumbnails: true # default is false. Use this if you want to replace http with https for thumbnails.
mediaBrowserTitle: My favorites # default is 'All favorites'. Use this to change the title for the media browser/favorites section.
sortFavoritesByType: true # default is false. Will group favorites by type (e.g. radio, playlist, album).

# volumes specific
hideVolumeCogwheel: true # default is false. Will hide the cogwheel for the volumes section.
Expand Down
37 changes: 32 additions & 5 deletions src/components/media-browser-icons.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { css, html, LitElement } from 'lit';
import { css, html, LitElement, nothing } from 'lit';
import { property } from 'lit/decorators.js';
import Store from '../model/store';
import { CardConfig, MediaPlayerItem } from '../types';
Expand All @@ -15,22 +15,37 @@ export class MediaBrowserIcons extends LitElement {
render() {
this.config = this.store.config;

const items = itemsWithFallbacks(this.items, this.config);
let prevType: string | undefined = '';
this.sortItemsByFavoriteTypeIfConfigured(items);
return html`
<div class="icons">
${itemsWithFallbacks(this.items, this.config).map(
(item) => html`
${items.map((item) => {
const showFavoriteType = (this.config.sortFavoritesByType && item.favoriteType !== prevType) || nothing;
const toRender = html`
<div class="favorite-type" show=${showFavoriteType}>${item.favoriteType}</div>
<ha-control-button
style=${this.buttonStyle(this.config.favoritesItemsPerRow || 4)}
@click=${() => this.dispatchEvent(customEvent(MEDIA_ITEM_SELECTED, item))}
>
${renderMediaBrowserItem(item, !item.thumbnail || !this.config.favoritesHideTitleForThumbnailIcons)}
</ha-control-button>
`,
)}
`;
prevType = item.favoriteType;
return toRender;
})}
</div>
`;
}

private sortItemsByFavoriteTypeIfConfigured(items: MediaPlayerItem[]) {
if (this.config.sortFavoritesByType) {
items.sort((a, b) => {
return a.favoriteType?.localeCompare(b.favoriteType ?? '') || a.title.localeCompare(b.title);
});
}
}

private buttonStyle(favoritesItemsPerRow: number) {
const margin = '1%';
const size = `calc(100% / ${favoritesItemsPerRow} - ${margin} * 2)`;
Expand Down Expand Up @@ -67,6 +82,18 @@ export class MediaBrowserIcons extends LitElement {
bottom: 0;
background-color: rgba(var(--rgb-card-background-color), 0.733);
}
.favorite-type {
width: 100%;
border-bottom: 1px solid var(--secondary-background-color);
display: none;
margin-top: 0.2rem;
font-weight: bold;
}
.favorite-type[show] {
display: block;
}
`,
];
}
Expand Down
4 changes: 4 additions & 0 deletions src/editor/advanced-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ export const ADVANCED_SCHEMA = [
name: 'inverseGroupMuteState',
selector: { boolean: {} },
},
{
name: 'sortFavoritesByType',
selector: { boolean: {} },
},
];

class AdvancedEditor extends BaseEditor {
Expand Down
2 changes: 1 addition & 1 deletion src/services/media-browse-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default class MediaBrowseService {
);
for (const child of dir.children ?? []) {
if (child.can_play) {
favorites.push(child);
favorites.push({ ...child, favoriteType: dir.title });
} else if (child.can_expand) {
await this.browseDir(player, child, favorites);
}
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export interface CardConfig extends LovelaceCardConfig {
mediaTitleReplacement?: string;
stopInsteadOfPause?: boolean;
inverseGroupMuteState?: boolean;
sortFavoritesByType?: boolean;
}

export interface MediaArtworkOverride {
Expand Down Expand Up @@ -137,6 +138,7 @@ export interface MediaPlayerItem {
media_class?: string;
media_content_type?: string;
media_content_id?: string;
favoriteType?: string;
}

export interface PredefinedGroup<T = PredefinedGroupPlayer> {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/media-browser-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function stringContainsAnyItemInArray(array: string[], str: string) {
return !!array.find((value) => str.includes(value));
}

export function itemsWithFallbacks(mediaPlayerItems: MediaPlayerItem[], config: CardConfig) {
export function itemsWithFallbacks(mediaPlayerItems: MediaPlayerItem[], config: CardConfig): MediaPlayerItem[] {
const itemsWithImage = hasItemsWithImage(mediaPlayerItems);
return mediaPlayerItems.map((item) => {
const thumbnail = getThumbnail(item, config, itemsWithImage);
Expand Down

0 comments on commit 8d6b1df

Please sign in to comment.