11import { CSSResultGroup , html , LitElement , TemplateResult } from "lit" ;
22import styles from '../styles/menu-item' ;
33import { customElement , property , state } from "lit/decorators.js" ;
4- import { ListImageData , ListItemData } from "../const/types" ;
4+ import { ExtendedHass , ListImageData , ListItemData } from "../const/types" ;
5+ import { tryPrefetchImageWithFallbacks } from "../utils/util.js" ;
6+ import { consume } from "@lit/context" ;
7+ import { hassContext } from "../const/context.js" ;
58
69@customElement ( 'mpc-menu-item' )
710export class MassMenuItem extends LitElement {
811 private _menuItem ! : ListItemData ;
912
13+ @consume ( { context : hassContext , subscribe : true } )
14+ private hass ! : ExtendedHass ;
1015 // Image/Icon Element
1116 @state ( ) imgOrIconTemplate ! : TemplateResult ;
1217
@@ -25,13 +30,21 @@ export class MassMenuItem extends LitElement {
2530 @property ( { attribute : false } )
2631 public set menuItem ( item : ListItemData ) {
2732 this . _menuItem = item ;
28- void this . setImageOrIconElement ( ) ;
33+ this . setImageOrIconElement ( ) ;
2934 }
3035 public get menuItem ( ) {
3136 return this . _menuItem ;
3237 }
33- private async setImageOrIconElement ( ) {
34- this . imgOrIconTemplate = await this . renderIconOrImage ( )
38+ private setImageOrIconElement ( ) {
39+ this . renderIconOrImage ( )
40+ }
41+
42+ private getImageCallback = ( src : string | boolean ) => {
43+ if ( typeof ( src ) == 'string' ) {
44+ this . imgOrIconTemplate = this . renderImage ( src )
45+ } else {
46+ this . imgOrIconTemplate = this . renderIcon ( ) ;
47+ }
3548 }
3649
3750 protected onSelection = ( ) => {
@@ -65,39 +78,21 @@ export class MassMenuItem extends LitElement {
6578 >
6679 `
6780 }
68- private async tryPrefetchImage ( image_url : string ) : Promise < string | boolean > {
69- if ( ! image_url ?. length || image_url . length < 10 ) {
70- return false ;
71- }
72- try {
73- const response = await fetch ( image_url )
74- if ( ! response . ok ) {
75- return false
76- }
77- const blob = await response . blob ( ) ;
78- return URL . createObjectURL ( blob ) ;
79- } catch {
80- return false
81- }
82- }
83- protected async renderImageFallbackOrIcon ( ) : Promise < TemplateResult > {
81+ protected renderImageFallbackOrIcon ( ) {
8482 const img_data = this . menuItem . image as ListImageData ;
85- const def_img_src = await this . tryPrefetchImage ( img_data . url ) ;
86- if ( typeof ( def_img_src ) == 'string' ) {
87- return this . renderImage ( def_img_src )
88- }
89-
90- const fallback_img_src = this . tryPrefetchImage ( img_data . fallback ) ;
91- if ( typeof ( fallback_img_src ) == 'string' ) {
92- return this . renderImage ( fallback_img_src )
93- }
94- return this . renderIcon ( )
83+ const img_url = img_data . url
84+ const fallbacks = [ img_data . fallback ]
85+ void tryPrefetchImageWithFallbacks ( img_url , fallbacks , this . hass ) . then (
86+ ( src ) => {
87+ this . getImageCallback ( src )
88+ }
89+ )
9590 }
96- protected async renderIconOrImage ( ) : Promise < TemplateResult > {
91+ protected renderIconOrImage ( ) {
9792 if ( this . menuItem ?. image ) {
98- return await this . renderImageFallbackOrIcon ( )
93+ this . renderImageFallbackOrIcon ( )
9994 }
100- return this . renderIcon ( )
95+ this . imgOrIconTemplate = this . renderIcon ( )
10196 }
10297
10398 protected renderDivider ( ) : TemplateResult {
0 commit comments