Skip to content

Commit 942904d

Browse files
committed
tap actions entities
1 parent ca14495 commit 942904d

2 files changed

Lines changed: 126 additions & 39 deletions

File tree

src/room-card-minimalist-editor.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,32 @@ class RoomCardEditor extends LitElement {
189189
type: 'grid',
190190
name: '',
191191
schema: [
192-
{
193-
name: 'use_light_color',
194-
label: 'Use Light Color',
195-
selector: { boolean: {} },
196-
},
197192
{
198193
name: 'tap_action',
199194
label: 'Tap Action',
200195
selector: { 'ui-action': {} },
201196
},
197+
{
198+
name: 'hold_action',
199+
label: 'Hold Action',
200+
selector: { 'ui-action': {} },
201+
},
202+
],
203+
},
204+
{
205+
type: 'grid',
206+
name: '',
207+
schema: [
208+
{
209+
name: 'double_tap_action',
210+
label: 'Double Tap Action',
211+
selector: { 'ui-action': {} },
212+
},
213+
{
214+
name: 'use_light_color',
215+
label: 'Use Light Color',
216+
selector: { boolean: {} },
217+
},
202218
],
203219
},
204220
];

src/room-card-minimalist.js

Lines changed: 105 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,14 @@ class RoomCard extends LitElement {
225225
@pointerdown=${this._handleHoldAction}
226226
>
227227
<div class="container">
228-
<div class="content-left">
228+
<div class="content-main">
229+
<div class="text-content">
230+
<span class="primary">${this._config.name}</span>
231+
${secondary
232+
? html`<span class="secondary">${secondary}</span>`
233+
: ''}
234+
</div>
235+
229236
<div class="icon-container">
230237
${this._config.show_background_circle !== false
231238
? html`
@@ -246,13 +253,6 @@ class RoomCard extends LitElement {
246253
<ha-icon .icon=${this._config.icon} />
247254
</div>
248255
</div>
249-
250-
<div class="text-content">
251-
<span class="primary">${this._config.name}</span>
252-
${secondary
253-
? html`<span class="secondary">${secondary}</span>`
254-
: ''}
255-
</div>
256256
</div>
257257
258258
<div class="content-right">
@@ -343,6 +343,7 @@ class RoomCard extends LitElement {
343343
class="state-item"
344344
style="background-color: ${background_color}"
345345
@click=${(e) => this._handleEntityClick(e, item)}
346+
@pointerdown=${(e) => this._handleEntityHoldAction(e, item)}
346347
>
347348
<ha-icon
348349
class="state-icon ${iconClass}"
@@ -357,6 +358,81 @@ class RoomCard extends LitElement {
357358
_handleEntityClick(e, item) {
358359
e.stopPropagation(); // Prevent triggering the card's main action
359360

361+
if (item._entityHoldFired) {
362+
item._entityHoldFired = false;
363+
return;
364+
}
365+
366+
// Handle double tap
367+
if (!item.double_tap_action) {
368+
this._executeEntityAction(item, 'tap');
369+
return;
370+
}
371+
372+
if (item._entityClickTimer == null) {
373+
item._entityClickTimer = setTimeout(() => {
374+
this._executeEntityAction(item, 'tap');
375+
item._entityClickTimer = null;
376+
}, 200);
377+
} else {
378+
clearTimeout(item._entityClickTimer);
379+
this._executeEntityAction(item, 'double_tap');
380+
item._entityClickTimer = null;
381+
}
382+
}
383+
384+
// Handle entity hold action
385+
_handleEntityHoldAction(e, item) {
386+
e.preventDefault();
387+
e.stopPropagation();
388+
389+
item._entityHoldFired = false;
390+
391+
const holdTimeout = setTimeout(() => {
392+
item._entityHoldFired = true;
393+
if (item.hold_action) {
394+
this._executeEntityAction(item, 'hold');
395+
}
396+
}, 300);
397+
398+
const cleanup = () => {
399+
clearTimeout(holdTimeout);
400+
item._entityHoldFired = false;
401+
402+
e.target.removeEventListener('pointerup', endHandler);
403+
e.target.removeEventListener('pointercancel', endHandler);
404+
document.removeEventListener('pointerup', endHandler);
405+
};
406+
407+
const endHandler = (e) => {
408+
e.preventDefault();
409+
cleanup();
410+
};
411+
412+
e.target.addEventListener('pointerup', endHandler, { once: true });
413+
e.target.addEventListener('pointercancel', endHandler, { once: true });
414+
document.addEventListener('pointerup', endHandler, { once: true });
415+
}
416+
417+
// Execute entity action based on type
418+
_executeEntityAction(item, actionType) {
419+
let action = this._getDefaultEntityAction(item);
420+
421+
// Override with custom action if provided
422+
if (actionType === 'tap' && item.tap_action) {
423+
action = item.tap_action;
424+
} else if (actionType === 'hold' && item.hold_action) {
425+
action = item.hold_action;
426+
} else if (actionType === 'double_tap' && item.double_tap_action) {
427+
action = item.double_tap_action;
428+
}
429+
430+
// Execute the action
431+
this._executeAction(action, item.entity);
432+
}
433+
434+
// Get default action for entity
435+
_getDefaultEntityAction(item) {
360436
// Default action based on entity type
361437
let action = {
362438
action: 'more-info',
@@ -388,13 +464,7 @@ class RoomCard extends LitElement {
388464
}
389465
}
390466

391-
// Override with custom tap_action if provided
392-
if (item.tap_action) {
393-
action = item.tap_action;
394-
}
395-
396-
// Execute the action
397-
this._executeAction(action, item.entity);
467+
return action;
398468
}
399469

400470
// Execute an action
@@ -655,8 +725,8 @@ class RoomCard extends LitElement {
655725
--main-color: rgb(var(--rgb-grey));
656726
--icon-size: 2.5rem;
657727
--icon-background-size: 3.5rem;
658-
--state-icon-size: 1.2rem;
659-
--state-item-size: 2rem;
728+
--state-icon-size: 1.8rem;
729+
--state-item-size: 45px;
660730
--card-primary-font-size: 16px;
661731
--card-primary-font-weight: 600;
662732
--card-primary-line-height: 1.3;
@@ -686,28 +756,37 @@ class RoomCard extends LitElement {
686756
687757
.container {
688758
display: flex;
689-
align-items: center;
759+
align-items: stretch;
690760
justify-content: space-between;
691761
padding: 16px;
692-
min-height: 72px;
762+
min-height: 90px;
693763
position: relative;
694764
z-index: 2;
695765
}
696766
697-
.content-left {
767+
.content-main {
698768
display: flex;
699-
align-items: center;
700-
gap: 12px;
769+
flex-direction: column;
770+
justify-content: space-between;
701771
flex: 1;
702772
min-width: 0;
703773
}
704774
775+
.text-content {
776+
display: flex;
777+
flex-direction: column;
778+
justify-content: flex-start;
779+
min-width: 0;
780+
margin-bottom: 8px;
781+
}
782+
705783
.icon-container {
706784
position: relative;
707785
display: flex;
708786
align-items: center;
709-
justify-content: center;
787+
justify-content: flex-start;
710788
flex-shrink: 0;
789+
align-self: flex-end;
711790
}
712791
713792
.icon-background {
@@ -735,14 +814,6 @@ class RoomCard extends LitElement {
735814
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
736815
}
737816
738-
.text-content {
739-
display: flex;
740-
flex-direction: column;
741-
justify-content: center;
742-
min-width: 0;
743-
flex: 1;
744-
}
745-
746817
.primary {
747818
font-weight: var(--card-primary-font-weight);
748819
font-size: var(--card-primary-font-size);
@@ -831,14 +902,14 @@ class RoomCard extends LitElement {
831902
@media (max-width: 768px) {
832903
.container {
833904
padding: 12px;
834-
min-height: 64px;
905+
min-height: 76px;
835906
}
836907
837908
:host {
838909
--icon-size: 2rem;
839910
--icon-background-size: 3rem;
840-
--state-item-size: 1.8rem;
841-
--state-icon-size: 1rem;
911+
--state-item-size: 38px;
912+
--state-icon-size: 1.4rem;
842913
}
843914
}
844915
`;

0 commit comments

Comments
 (0)