From 6662c95a9ea56cfac017a8a3f75360e376d07419 Mon Sep 17 00:00:00 2001 From: Viet Ngoc Date: Wed, 22 Jan 2025 01:00:05 +0100 Subject: [PATCH] :robot: 22-01-25 | :recycle: Updated 6 files :sparkles: Added 2 files -------- - update: govee/manifest.json - update: subviews/github-stats.yaml - update: main-grid/a-chips.yaml - update: floorplan/lights.yaml - update: config/README.md - update: docs/README.md - add: dashboard-resources/extra-menu.js - add: extra-popup/ -------- Automated commit via script --- config/README.md | 6 +- config/custom_components/govee/manifest.json | 2 +- config/dashboards/floorplan/lights.yaml | 3 + .../shared/extra-popup/mass-homepods.yaml | 11 ++ .../shared/extra-popup/vanessa.yaml | 8 + config/dashboards/subviews/github-stats.yaml | 13 +- .../dashboards/views/main-grid/a-chips.yaml | 1 + config/www/dashboard-resources/extra-menu.js | 187 ++++++++++++++++++ docs/README.md | 6 +- 9 files changed, 227 insertions(+), 10 deletions(-) create mode 100644 config/dashboards/shared/extra-popup/mass-homepods.yaml create mode 100644 config/dashboards/shared/extra-popup/vanessa.yaml create mode 100644 config/www/dashboard-resources/extra-menu.js diff --git a/config/README.md b/config/README.md index 52d583e..4aee8b1 100644 --- a/config/README.md +++ b/config/README.md @@ -10,7 +10,7 @@ Hey there! Welcome to my little corner of the tech world! 👨‍💻 This is where I store all the cool configurations for my Home Assistant system. Well, it's a mix of awesome codes and setups I discovered from the Home Assistant community. Seriously, those folks are wizards! 🧙‍♂️ As a bit of an internet newbie turned tech enthusiast, I stumbled upon the magic of IT, and this repository is my way of sharing the joy and knowledge I've gained along the way. Dive in, explore, and let the tech magic begin! ✨ -I frequently refresh my configuration files. My current Home Assistant version is 2025.1.2. If you find something you like, don't forget to give my repository a ⭐️! +I frequently refresh my configuration files. My current Home Assistant version is 2025.1.3. If you find something you like, don't forget to give my repository a ⭐️! ## Some of my projects for Home Assistant @@ -45,13 +45,13 @@ https://github.com/ngocjohn/hass-config/assets/96962827/acc1a4db-b92e-4ab1-ac9d- - 35,268 + 35,325 34 164 63 54 32 - 1071 + 1072 215 38 diff --git a/config/custom_components/govee/manifest.json b/config/custom_components/govee/manifest.json index 363300b..dd3ee4f 100644 --- a/config/custom_components/govee/manifest.json +++ b/config/custom_components/govee/manifest.json @@ -10,6 +10,6 @@ "issue_tracker": "https://github.com/LaggAt/hacs-govee/issues", "requirements": ["govee-api-laggat==0.2.2", "dacite==1.8.0"], "ssdp": [], - "version": "2023.11.1", + "version": "2025.1.1", "zeroconf": [] } diff --git a/config/dashboards/floorplan/lights.yaml b/config/dashboards/floorplan/lights.yaml index c5cd199..ae335e3 100755 --- a/config/dashboards/floorplan/lights.yaml +++ b/config/dashboards/floorplan/lights.yaml @@ -131,3 +131,6 @@ - light.shelly_rgbw_kitchen_led_strip - light.living_room_floor_lamp hold_action: !include ../shared/honeycomb/living.yaml +- entities: + - light.vanesska_ceiling_light + hold_action: !include ../shared/extra-popup/vanessa.yaml diff --git a/config/dashboards/shared/extra-popup/mass-homepods.yaml b/config/dashboards/shared/extra-popup/mass-homepods.yaml new file mode 100644 index 0000000..866610b --- /dev/null +++ b/config/dashboards/shared/extra-popup/mass-homepods.yaml @@ -0,0 +1,11 @@ +action: fire-dom-event +extra_menu: + cards: + - type: custom:auto-entities + card: + type: entities + theme: Graphite Auto + filter: + include: + - label: Mass Homepod + exclude: [] diff --git a/config/dashboards/shared/extra-popup/vanessa.yaml b/config/dashboards/shared/extra-popup/vanessa.yaml new file mode 100644 index 0000000..93b5f11 --- /dev/null +++ b/config/dashboards/shared/extra-popup/vanessa.yaml @@ -0,0 +1,8 @@ +action: fire-dom-event +extra_menu: + custom_position: bottom-right + card_container: + padding: 1vw + cards: + - type: custom:webrtc-camera + entity: camera.kids_room_cam diff --git a/config/dashboards/subviews/github-stats.yaml b/config/dashboards/subviews/github-stats.yaml index e70f8d5..fe9929c 100644 --- a/config/dashboards/subviews/github-stats.yaml +++ b/config/dashboards/subviews/github-stats.yaml @@ -6,7 +6,7 @@ theme: tablet xbackground: >- linear-gradient(170deg, rgba(22, 24, 29, 0.6) 80%, rgba(156, 156, 210, 0.6) 160%) type: sections -max_columns: 9 +max_columns: 8 dense_section_placement: true sections: - type: grid @@ -202,16 +202,23 @@ sections: secondary_info: last-changed icon: mdi:source-commit name: Latest Commit + tap_action: + action: fire-dom-event + browser_mod: + service: browser_mod.javascript + data: + code: > + window.open(`${hass.states['sensor.hass_config_latest_commit'].attributes.url}`, '_blank'); - type: divider - type: custom:multiple-logbook-card card_mod: style: | ha-card .card-content-scroll { padding: 0 !important; - max-height: 325px; + max-height: 270px; height: 100%; } - max_items: 7 + max_items: 6 show: separator: true duration: false diff --git a/config/dashboards/views/main-grid/a-chips.yaml b/config/dashboards/views/main-grid/a-chips.yaml index 8fc83b1..e4f82be 100755 --- a/config/dashboards/views/main-grid/a-chips.yaml +++ b/config/dashboards/views/main-grid/a-chips.yaml @@ -63,6 +63,7 @@ service: browser_mod.more_info data: entity: media_player.currently_playing + hold_action: !include ../../shared/extra-popup/mass-homepods.yaml # - &homemode # type: custom:button-card diff --git a/config/www/dashboard-resources/extra-menu.js b/config/www/dashboard-resources/extra-menu.js new file mode 100644 index 0000000..6454ec4 --- /dev/null +++ b/config/www/dashboard-resources/extra-menu.js @@ -0,0 +1,187 @@ +function t(t,e,s,i){var o,n=arguments.length,r=n<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,s):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,s,i);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(r=(n<3?o(r):n>3?o(e,s,r):o(e,s))||r);return n>3&&r&&Object.defineProperty(e,s,r),r}function e(t,e,s){return null==s?Math.min(t,e):Math.min(Math.max(t,e),s)} +/** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */console.groupCollapsed("%c EXTRA-MENU \n%c v0.0.1 ","color: orange; font-weight: bold; background: transparent","font-weight: bold; background: dimgray"),console.info("Extra popup menu for Home Assistant"),console.info("Github: https://github.com/ngocjohn/extra-menu"),console.info("If you like the card, consider supporting the developer: https://github.com/sponsors/ngocjohn"),console.groupEnd(),"function"==typeof SuppressedError&&SuppressedError;const s=globalThis,i=s.ShadowRoot&&(void 0===s.ShadyCSS||s.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,o=Symbol(),n=new WeakMap;let r=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==o)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const e=this.t;if(i&&void 0===t){const s=void 0!==e&&1===e.length;s&&(t=n.get(e)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),s&&n.set(e,t))}return t}toString(){return this.cssText}};const a=t=>new r("string"==typeof t?t:t+"",void 0,o),h=(t,...e)=>{const s=1===t.length?t[0]:e.reduce(((e,s,i)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+t[i+1]),t[0]);return new r(s,t,o)},l=(t,e)=>{if(i)t.adoptedStyleSheets=e.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const i of e){const e=document.createElement("style"),o=s.litNonce;void 0!==o&&e.setAttribute("nonce",o),e.textContent=i.cssText,t.appendChild(e)}},c=i?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return a(e)})(t):t +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */,{is:d,defineProperty:p,getOwnPropertyDescriptor:u,getOwnPropertyNames:f,getOwnPropertySymbols:m,getPrototypeOf:$}=Object,y=globalThis,_=y.trustedTypes,g=_?_.emptyScript:"",v=y.reactiveElementPolyfillSupport,A=(t,e)=>t,b={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let s=t;switch(e){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t)}catch(t){s=null}}return s}},w=(t,e)=>!d(t,e),E={attribute:!0,type:String,converter:b,reflect:!1,hasChanged:w};Symbol.metadata??=Symbol("metadata"),y.litPropertyMetadata??=new WeakMap;class S extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=E){if(e.state&&(e.attribute=!1),this._$Ei(),this.elementProperties.set(t,e),!e.noAccessor){const s=Symbol(),i=this.getPropertyDescriptor(t,s,e);void 0!==i&&p(this.prototype,t,i)}}static getPropertyDescriptor(t,e,s){const{get:i,set:o}=u(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get(){return i?.call(this)},set(e){const n=i?.call(this);o.call(this,e),this.requestUpdate(t,n,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??E}static _$Ei(){if(this.hasOwnProperty(A("elementProperties")))return;const t=$(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(A("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(A("properties"))){const t=this.properties,e=[...f(t),...m(t)];for(const s of e)this.createProperty(s,t[s])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,s]of e)this.elementProperties.set(t,s)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const s=this._$Eu(t,e);void 0!==s&&this._$Eh.set(s,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const s=new Set(t.flat(1/0).reverse());for(const t of s)e.unshift(c(t))}else void 0!==t&&e.push(c(t));return e}static _$Eu(t,e){const s=e.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const s of e.keys())this.hasOwnProperty(s)&&(t.set(s,this[s]),delete this[s]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return l(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,e,s){this._$AK(t,s)}_$EC(t,e){const s=this.constructor.elementProperties.get(t),i=this.constructor._$Eu(t,s);if(void 0!==i&&!0===s.reflect){const o=(void 0!==s.converter?.toAttribute?s.converter:b).toAttribute(e,s.type);this._$Em=t,null==o?this.removeAttribute(i):this.setAttribute(i,o),this._$Em=null}}_$AK(t,e){const s=this.constructor,i=s._$Eh.get(t);if(void 0!==i&&this._$Em!==i){const t=s.getPropertyOptions(i),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:b;this._$Em=i,this[i]=o.fromAttribute(e,t.type),this._$Em=null}}requestUpdate(t,e,s){if(void 0!==t){if(s??=this.constructor.getPropertyOptions(t),!(s.hasChanged??w)(this[t],e))return;this.P(t,e,s)}!1===this.isUpdatePending&&(this._$ES=this._$ET())}P(t,e,s){this._$AL.has(t)||this._$AL.set(t,e),!0===s.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t)}async _$ET(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,s]of t)!0!==s.wrapped||this._$AL.has(e)||void 0===this[e]||this.P(e,this[e],s)}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(e)):this._$EU()}catch(e){throw t=!1,this._$EU(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EU(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Ej&&=this._$Ej.forEach((t=>this._$EC(t,this[t]))),this._$EU()}updated(t){}firstUpdated(t){}}S.elementStyles=[],S.shadowRootOptions={mode:"open"},S[A("elementProperties")]=new Map,S[A("finalized")]=new Map,v?.({ReactiveElement:S}),(y.reactiveElementVersions??=[]).push("2.0.4"); +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const C=globalThis,x=C.trustedTypes,P=x?x.createPolicy("lit-html",{createHTML:t=>t}):void 0,O="$lit$",T=`lit$${Math.random().toFixed(9).slice(2)}$`,U="?"+T,R=`<${U}>`,M=document,H=()=>M.createComment(""),k=t=>null===t||"object"!=typeof t&&"function"!=typeof t,N=Array.isArray,j=t=>N(t)||"function"==typeof t?.[Symbol.iterator],L="[ \t\n\f\r]",I=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,q=/-->/g,B=/>/g,D=RegExp(`>|${L}(?:([^\\s"'>=/]+)(${L}*=${L}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),z=/'/g,W=/"/g,V=/^(?:script|style|textarea|title)$/i,X=t=>(e,...s)=>({_$litType$:t,strings:e,values:s}),Y=X(1),F=Symbol.for("lit-noChange"),Z=Symbol.for("lit-nothing"),J=new WeakMap,K=M.createTreeWalker(M,129);function G(t,e){if(!N(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==P?P.createHTML(e):e}const Q=(t,e)=>{const s=t.length-1,i=[];let o,n=2===e?"":3===e?"":"",r=I;for(let e=0;e"===h[0]?(r=o??I,l=-1):void 0===h[1]?l=-2:(l=r.lastIndex-h[2].length,a=h[1],r=void 0===h[3]?D:'"'===h[3]?W:z):r===W||r===z?r=D:r===q||r===B?r=I:(r=D,o=void 0);const d=r===D&&t[e+1].startsWith("/>")?" ":"";n+=r===I?s+R:l>=0?(i.push(a),s.slice(0,l)+O+s.slice(l)+T+d):s+T+(-2===l?e:d)}return[G(t,n+(t[s]||"")+(2===e?"":3===e?"":"")),i]};class tt{constructor({strings:t,_$litType$:e},s){let i;this.parts=[];let o=0,n=0;const r=t.length-1,a=this.parts,[h,l]=Q(t,e);if(this.el=tt.createElement(h,s),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(i=K.nextNode())&&a.length0){i.textContent=x?x.emptyScript:"";for(let s=0;s2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=Z}_$AI(t,e=this,s,i){const o=this.strings;let n=!1;if(void 0===o)t=et(this,t,e,0),n=!k(t)||t!==this._$AH&&t!==F,n&&(this._$AH=t);else{const i=t;let r,a;for(t=o[0],r=0;r{const i=s?.renderBefore??e;let o=i._$litPart$;if(void 0===o){const t=s?.renderBefore??null;i._$litPart$=o=new it(e.insertBefore(H(),t),t,void 0,s??{})}return o._$AI(t),o +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */};let dt=class extends S{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=ct(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return F}};dt._$litElement$=!0,dt.finalized=!0,globalThis.litElementHydrateSupport?.({LitElement:dt});const pt=globalThis.litElementPolyfillSupport;pt?.({LitElement:dt}),(globalThis.litElementVersions??=[]).push("4.1.1"); +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const ut={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},ft=t=>(...e)=>({_$litDirective$:t,values:e});let mt=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,s){this._$Ct=t,this._$AM=e,this._$Ci=s}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}; +/** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */const $t="important",yt=" !"+$t,_t=ft(class extends mt{constructor(t){if(super(t),t.type!==ut.ATTRIBUTE||"style"!==t.name||t.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(t){return Object.keys(t).reduce(((e,s)=>{const i=t[s];return null==i?e:e+`${s=s.includes("-")?s:s.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${i};`}),"")}update(t,[e]){const{style:s}=t.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(e)),this.render(e);for(const t of this.ft)null==e[t]&&(this.ft.delete(t),t.includes("-")?s.removeProperty(t):s[t]=null);for(const t in e){const i=e[t];if(null!=i){this.ft.add(t);const e="string"==typeof i&&i.endsWith(yt);t.includes("-")||e?s.setProperty(t,e?i.slice(0,-11):i,e?$t:""):s[t]=i}}return F}}),gt=t=>(e,s)=>{void 0!==s?s.addInitializer((()=>{customElements.define(t,e)})):customElements.define(t,e)} +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */,vt={attribute:!0,type:String,converter:b,reflect:!1,hasChanged:w},At=(t=vt,e,s)=>{const{kind:i,metadata:o}=s;let n=globalThis.litPropertyMetadata.get(o);if(void 0===n&&globalThis.litPropertyMetadata.set(o,n=new Map),n.set(s.name,t),"accessor"===i){const{name:i}=s;return{set(s){const o=e.get.call(this);e.set.call(this,s),this.requestUpdate(i,o,t)},init(e){return void 0!==e&&this.P(i,void 0,t),e}}}if("setter"===i){const{name:i}=s;return function(s){const o=this[i];e.call(this,s),this.requestUpdate(i,o,t)}}throw Error("Unsupported decorator location: "+i)}; +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */function bt(t){return(e,s)=>"object"==typeof s?At(t,e,s):((t,e,s)=>{const i=e.hasOwnProperty(s);return e.constructor.createProperty(s,i?{...t,wrapped:!0}:t),i?Object.getOwnPropertyDescriptor(e,s):void 0})(t,e,s)}const wt={backgroundColor:"rgba(0, 0, 0, 0.32);",backdropFilter:"blur(5px)"},Et={maxWidth:"492px"};function St(){let t=document.querySelector("home-assistant");return t=t&&t.shadowRoot,t=t&&t.querySelector("home-assistant-main"),t=t&&t.shadowRoot,t=t&&t.querySelector("app-drawer-layout partial-panel-resolver")||t.querySelector("ha-drawer partial-panel-resolver"),t=t&&t.shadowRoot||t,t=t&&t.querySelector("ha-panel-lovelace"),t=t&&t.shadowRoot,t=t&&t.querySelector("hui-root"),t=t&&t.shadowRoot,t=t&&t.querySelector("ha-app-layout")||t,t=t&&t.querySelector("#view"),t=t&&t.querySelector("hui-view"),t}const Ct=window.loadCardHelpers?window.loadCardHelpers():void 0,xt=new function(){this.extraMenu=null,this.position={x:0,y:0},this.handleXYPosition=t=>{t instanceof MouseEvent?this.position={x:t.clientX,y:t.clientY}:t instanceof TouchEvent&&(this.position={x:t.touches[0].clientX,y:t.touches[0].clientY})}};function Pt(t){const e=St();e&&(xt.extraMenu=document.createElement("extra-menu"),xt.extraMenu.hass=e.hass,xt.extraMenu.view=e,xt.extraMenu.config=t,xt.extraMenu.position=xt.position,xt.extraMenu.createCard(t.cards))}document.body.addEventListener("ll-custom",(t=>{t.preventDefault();const e=t;e.detail.extra_menu&&Pt(e.detail.extra_menu)})),document.addEventListener("touchstart",xt.handleXYPosition,!1),document.addEventListener("mousedown",xt.handleXYPosition,!1);let Ot=class extends dt{constructor(){super(...arguments),this.cardElement=[],this._handleClose=t=>{t.stopPropagation(),this.close()}}connectedCallback(){super.connectedCallback(),window.extra_menu=this}disconnectedCallback(){super.disconnectedCallback()}async createCard(t){let e;if(window.loadCardHelpers?e=await window.loadCardHelpers():Ct&&(e=Ct),!e||!e.createCardElement)return;const s=await Promise.all(t.map((async t=>{try{const s=await e.createCardElement(t);return s.hass=this.hass,s}catch(t){return null}})));this.cardElement=s,this.cardElement&&this.cardElement.length>0&&this._handleShowCard()}render(){return Y` +
this._handleClose(t)}>
+ + `}_handleShowCard(){const t=this.config.custom_position;this.view.style.position="relative",this.view.appendChild(this);const e=this.config.card_container||{},s=Object.assign(Object.assign({},Et),e);setTimeout((()=>{t&&void 0!==t?this.setCustomPosition(t,s):(Object.assign(this.style,s),this.setPosition(this.position))}),200)}setCustomPosition(t,e){var s;const i=null===(s=this.shadowRoot)||void 0===s?void 0:s.querySelector("#card-container");i&&(this.classList.add(t),Object.assign(i.style,e),i.style.height="100%",i.style.width="100%",i.style.placeSelf="center center",i.classList.replace("hidden","fade-in"))}setPosition(t){var s;const i=null===(s=this.shadowRoot)||void 0===s?void 0:s.querySelector("#card-container"),o=i.getBoundingClientRect();let n=o.width/2,r=o.height/2,a={min:{x:parseFloat(window.getComputedStyle(this.view).getPropertyValue("padding-left"))+n,y:parseFloat(window.getComputedStyle(this.view).getPropertyValue("padding-top"))+r},max:{x:this.view.clientWidth-n,y:this.view.clientHeight-r}};const h=this.view.getBoundingClientRect();t.x=e(t.x-h.left,a.min.x,a.max.x-4),t.y=e(t.y-h.top,a.min.y,a.max.y-4),this.style.left=t.x-n+"px",this.style.top=t.y-r+"px",i.classList.replace("hidden","fade-in")}close(){var t,e;const s=null===(t=this.shadowRoot)||void 0===t?void 0:t.querySelector("#card-container"),i=null===(e=this.shadowRoot)||void 0===e?void 0:e.querySelector("#shadow-container");s&&i&&(s.classList.toggle("fade-out",!0),s.addEventListener("animationend",(()=>{s.classList.replace("fade-out","hidden"),xt.extraMenu=null,this.remove()})))}computeShadowStyle(){const t=this.config.shadow_container||{};return _t(Object.assign(Object.assign({},wt),t))}static get styles(){return h` + :host { + position: absolute; + z-index: 8; /*200;*/ + } + + :host([closing]), + :host([closing]) * { + pointer-events: none !important; + } + + #shadow-container { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + animation-duration: 1s; + animation-fill-mode: both; + animation-name: fadeIn; + } + + #card-container { + background: none; + border: none; + display: flex; + flex-direction: column; + justify-content: center; + gap: 8px; + } + + #card-container.hidden { + visibility: hidden; + } + // Custom Positions for the card container + :host(.top) { + top: 0; + left: 50%; + transform: translateX(-50%); + height: 100%; + width: 100%; + place-self: center center; + } + + :host(.bottom) { + bottom: 0; + left: 50%; + transform: translateX(-50%); + height: 100%; + width: 100%; + place-self: center center; + } + + :host(.left) { + left: 0; + top: 50%; + transform: translateY(-50%); + height: 100%; + width: 100%; + place-self: center center; + } + + :host(.right) { + right: 0; + top: 50%; + transform: translateY(-50%); + height: 100%; + width: 100%; + place-self: center center; + } + + :host(.center) { + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + height: 100%; + width: 100%; + place-self: center center; + } + + :host(.top-left) { + top: 0; + left: 0; + } + + :host(.top-right) { + top: 0; + right: 0; + } + + :host(.bottom-left) { + bottom: 0; + left: 0; + } + + :host(.bottom-right) { + bottom: 0; + right: 0; + } + + /* Card fade-in and fade-out animations */ + .fade-in { + animation: fadeIn 0.2s ease-in; + } + + .fade-out { + animation: fadeOut 0.3s ease-in-out; + } + + .clip-from-side { + animation: clipFromSide 1s ease-in-out forwards; + } + + @keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + + @keyframes fadeOut { + from { + opacity: 1; + transform: scale(1); + } + to { + opacity: 0; + transform: scale(0.5); + } + } + + @keyframes clipFromSide { + from { + clip-path: inset(0 0 0 0); + } + to { + clip-path: inset(0 100% 0 100%); + } + } + `}};t([bt({attribute:!1})],Ot.prototype,"hass",void 0),t([bt({attribute:!1})],Ot.prototype,"config",void 0),t([bt({attribute:!1})],Ot.prototype,"cardElement",void 0),t([bt({attribute:!1})],Ot.prototype,"view",void 0),t([bt({attribute:!1})],Ot.prototype,"position",void 0),Ot=t([gt("extra-menu")],Ot);export{Ot as ExtraMenu}; diff --git a/docs/README.md b/docs/README.md index 52d583e..4aee8b1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,7 +10,7 @@ Hey there! Welcome to my little corner of the tech world! 👨‍💻 This is where I store all the cool configurations for my Home Assistant system. Well, it's a mix of awesome codes and setups I discovered from the Home Assistant community. Seriously, those folks are wizards! 🧙‍♂️ As a bit of an internet newbie turned tech enthusiast, I stumbled upon the magic of IT, and this repository is my way of sharing the joy and knowledge I've gained along the way. Dive in, explore, and let the tech magic begin! ✨ -I frequently refresh my configuration files. My current Home Assistant version is 2025.1.2. If you find something you like, don't forget to give my repository a ⭐️! +I frequently refresh my configuration files. My current Home Assistant version is 2025.1.3. If you find something you like, don't forget to give my repository a ⭐️! ## Some of my projects for Home Assistant @@ -45,13 +45,13 @@ https://github.com/ngocjohn/hass-config/assets/96962827/acc1a4db-b92e-4ab1-ac9d- - 35,268 + 35,325 34 164 63 54 32 - 1071 + 1072 215 38