Skip to content

Commit

Permalink
add lots of modal support
Browse files Browse the repository at this point in the history
  • Loading branch information
matt8707 committed Jan 2, 2024
1 parent 9ac56b0 commit dbf0620
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 68 deletions.
24 changes: 12 additions & 12 deletions src/lib/Drawer/Index.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
<script lang="ts">
import { dashboard, editMode, history, historyIndex, motion } from '$lib/Stores';
import Separator from '$lib/Drawer/Separator.svelte';
import { onMount } from 'svelte';
import { slide } from 'svelte/transition';
import '$lib/Drawer/Drawer.css';
import Separator from '$lib/Drawer/Separator.svelte';
export let view: any;
export let data: any;
import type { Configuration, Dashboard, Translations, ViewItem } from '$lib/Types';
export let data: {
configuration: Configuration;
dashboard: Dashboard;
theme: any;
translations: Translations;
};
export let view: ViewItem | undefined;
export let toggleDrawer: () => void;
/**
* BETA: Only display SayButton in Chrome
*/
/** Only display SayButton in Chrome */
let chrome: boolean;
onMount(() => {
chrome = navigator?.userAgent?.indexOf('Chrome') > -1;
});
Expand Down Expand Up @@ -75,9 +77,7 @@
<svelte:component this={SaveButton.default} {modified} />
{/await}
</div>
{/if}

{#if !$editMode}
{:else}
{#await import('$lib/Drawer/CodeButton.svelte') then CodeButton}
<svelte:component this={CodeButton.default} />
{/await}
Expand Down
122 changes: 94 additions & 28 deletions src/lib/Main/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -74,33 +74,59 @@
/**
* Toggles the state of the specified entity
* using the `homeassistant.toggle` service
* using the correct service call...
*/
function toggle() {
const domain = getDomain(sel?.entity_id);
if (domain === 'timer') {
const service = entity?.state === 'active' ? 'pause' : 'start';
callService($connection, 'timer', service, {
entity_id: entity?.entity_id
});
} else if (domain === 'person') {
console.debug('shortcut to ping iphone?');
return;
} else {
callService($connection, 'homeassistant', 'toggle', {
entity_id: entity?.entity_id
});
const domain = getDomain(entity_id);
const state = entity?.state;
if (!domain || !state) return;
const services: Record<string, string> = {
automation: 'toggle',
button: 'press',
cover: 'toggle',
fan: 'toggle',
humidifier: 'toggle',
input_boolean: 'toggle',
input_button: 'press',
light: 'toggle',
lock: state === 'locked' ? 'unlock' : 'lock',
media_player: 'toggle',
scene: 'turn_on',
script: 'toggle',
siren: 'toggle',
switch: 'toggle',
timer: state === 'active' ? 'pause' : 'start',
vacuum: 'toggle'
};
switch (domain) {
case 'person':
console.debug('ping phone?');
break;
case 'remote':
callService($connection, 'homeassistant', 'toggle', { entity_id });
break;
default:
if (domain in services) {
callService($connection, domain, services[domain], { entity_id });
// loader
delayLoading = setTimeout(() => {
loading = true;
}, $motion);
// loader 20s fallback
resetLoading = setTimeout(() => {
loading = false;
}, 20_000);
} else {
// not listed above just open modal
handleClickEvent();
}
}
delayLoading = setTimeout(() => {
loading = true;
}, $motion);
// remove loader after 20s if state never changes (fallback)
resetLoading = setTimeout(() => {
loading = false;
}, 20_000);
}
/**
Expand Down Expand Up @@ -134,24 +160,64 @@
});
} else {
switch (getDomain(sel?.entity_id)) {
// light
case 'light':
openModal(() => import('$lib/Modal/LightModal.svelte'), {
sel: sel
});
break;
// switch
case 'automation':
case 'input_boolean':
case 'remote':
case 'siren':
case 'switch':
openModal(() => import('$lib/Modal/SwitchModal.svelte'), {
selected: sel
});
case 'script':
openModal(() => import('$lib/Modal/SwitchModal.svelte'), { sel });
break;
// sensor
case 'air_quality':
case 'calendar':
case 'event':
case 'image_processing':
case 'mailbox':
case 'sensor':
case 'binary_sensor':
case 'stt':
case 'update':
case 'weather':
case 'button':
case 'scene':
case 'schedule':
case 'sun':
case 'input_button':
openModal(() => import('$lib/Modal/SensorModal.svelte'), { sel });
break;
case 'timer':
openModal(() => import('$lib/Modal/TimerModal.svelte'), { entity_id });
openModal(() => import('$lib/Modal/TimerModal.svelte'), {
entity_id
});
break;
case 'alarm_control_panel':
openModal(() => import('$lib/Modal/AlarmControlPanelModal.svelte'), {
sel
});
break;
case 'lock':
openModal(() => import('$lib/Modal/LockModal.svelte'), { sel });
break;
case 'climate':
openModal(() => import('$lib/Modal/ClimateModal.svelte'), {
selected: sel
});
break;
case 'camera':
openModal(() => import('$lib/Modal/CameraModal.svelte'), {
entity_id: sel?.entity_id
Expand Down
49 changes: 27 additions & 22 deletions src/lib/Modal/ClimateModal.svelte
Original file line number Diff line number Diff line change
@@ -1,49 +1,55 @@
<script lang="ts">
import { states, lang } from '$lib/Stores';
import { states, lang, connection } from '$lib/Stores';
import Modal from '$lib/Modal/Index.svelte';
import WheelPicker from '$lib/Components/WheelPicker.svelte';
import Icon from '@iconify/svelte';
import ConfigButtons from '$lib/Modal/ConfigButtons.svelte';
import { getName } from '$lib/Utils';
import { callService } from 'home-assistant-js-websocket';
export let isOpen: boolean;
export let selected: any;
$: entity = $states[selected?.entity_id];
$: entity_id = entity?.entity_id;
$: attributes = entity?.attributes;
function handleClick(service: string, to_state: string) {
const service_data = {
service: 'climate.set_' + service,
data: {
[service]: to_state
}
};
console.debug(JSON.stringify(service_data, null, 2));
callService($connection, 'climate', 'set_' + service, {
entity_id,
[service]: to_state
});
console.debug('climate.set_' + service, '->', to_state);
}
const hvacModesIcons: Record<string, string> = {
auto: 'mdi:thermostat-auto',
heat: 'mdi:fire',
heat_cool: 'mdi:sun-snowflake-variant',
cool: 'mdi:snowflake',
dry: 'mdi:water-percent',
off: 'mdi:power',
fan_only: 'mdi:fan'
};
</script>

{#if isOpen}
<Modal>
<h1 slot="title">{getName(selected, entity)}</h1>

<h2>{$lang('hvac_modes')}</h2>

{#if attributes?.hvac_modes}
<h2>{$lang('hvac_modes')}</h2>

<div class="button-container">
{#each attributes?.hvac_modes as hvacMode}
<button
title={$lang(hvacMode)}
on:click={() => handleClick('hvac_mode', hvacMode)}
class:selected={hvacMode === entity?.state}
>
<div class="icon-test">
{#if hvacMode === 'off'}
<Icon icon="mdi:power" height="none" />
{:else if hvacMode === 'cool'}
<Icon icon="mdi:snowflake" height="none" />
{:else if hvacMode === 'fan_only'}
<Icon icon="mdi:fan" height="none" />
{/if}
<Icon icon={hvacModesIcons?.[hvacMode]} height="none" />
</div>
</button>
{/each}
Expand All @@ -59,9 +65,9 @@
}}
/>

<h2>{$lang('fan_modes')}</h2>

{#if attributes?.fan_modes}
<h2>{$lang('fan_modes')}</h2>

<div class="button-container">
{#each attributes?.fan_modes as fanMode}
<button
Expand All @@ -74,9 +80,9 @@
</div>
{/if}

<h2>{$lang('swing_modes')}</h2>

{#if attributes?.swing_modes}
<h2>{$lang('swing_modes')}</h2>

<div class="button-container">
{#each attributes?.swing_modes as swingMode}
<button
Expand All @@ -103,6 +109,5 @@
vertical-align: middle;
display: inline-block;
color: inherit;
pointer-events: none;
}
</style>
33 changes: 33 additions & 0 deletions src/lib/Modal/LockModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
import { states, connection, lang } from '$lib/Stores';
import { callService } from 'home-assistant-js-websocket';
import Toggle from '$lib/Components/Toggle.svelte';
import ConfigButtons from '$lib/Modal/ConfigButtons.svelte';
import Modal from '$lib/Modal/Index.svelte';
import { getName } from '$lib/Utils';
export let isOpen: boolean;
export let sel: any;
$: entity = $states[sel?.entity_id];
$: entity_id = entity?.entity_id;
$: state = entity?.state;
$: toggle = entity?.state === 'unlocked';
function handleClick() {
const service = state === 'locked' ? 'unlock' : 'lock';
callService($connection, 'lock', service, { entity_id });
}
</script>

{#if isOpen}
<Modal>
<h1 slot="title">{getName(sel, entity)}</h1>

<h2>{$lang('toggle')}</h2>

<Toggle bind:checked={toggle} on:change={handleClick} />

<ConfigButtons />
</Modal>
{/if}
24 changes: 24 additions & 0 deletions src/lib/Modal/SensorModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { states, lang } from '$lib/Stores';
import Modal from '$lib/Modal/Index.svelte';
import StateLogic from '$lib/Components/StateLogic.svelte';
import ConfigButtons from '$lib/Modal/ConfigButtons.svelte';
import { getName } from '$lib/Utils';
export let isOpen: boolean;
export let sel: any;
$: entity = $states[sel?.entity_id];
</script>

{#if isOpen}
<Modal>
<h1 slot="title">{getName(sel, entity)}</h1>

<h2>{$lang('state')}</h2>

<StateLogic entity_id={sel?.entity_id} selected={sel} />

<ConfigButtons />
</Modal>
{/if}
10 changes: 4 additions & 6 deletions src/lib/Modal/SwitchModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,29 @@
import { getName } from '$lib/Utils';
export let isOpen: boolean;
export let selected: any;
export let sel: any;
$: entity = $states[selected?.entity_id];
$: entity = $states[sel?.entity_id];
$: toggle = entity?.state === 'on';
/**
* Calls switch.toggle service
*/
function handleClick() {
callService($connection, 'switch', 'toggle', {
callService($connection, 'homeassistant', 'toggle', {
entity_id: entity?.entity_id
});
}
</script>

{#if isOpen}
<Modal>
<h1 slot="title">{getName(selected, entity)}</h1>
<h1 slot="title">{getName(sel, entity)}</h1>

<h2>{$lang('toggle')}</h2>

<Toggle bind:checked={toggle} on:change={handleClick} />

<br />

<ConfigButtons />
</Modal>
{/if}

0 comments on commit dbf0620

Please sign in to comment.