Implement alarm sound

This commit is contained in:
nemunaire 2022-10-14 20:08:03 +02:00
commit 8faa21ccab
15 changed files with 531 additions and 50 deletions

46
ui/src/lib/alarm.js Normal file
View file

@ -0,0 +1,46 @@
export async function isAlarmActive() {
const res = await fetch('api/alarm', {
headers: {'Accept': 'application/json'},
});
if (res.status == 200) {
return await res.json();
} else {
throw new Error((await res.json()).errmsg);
}
}
export async function runAlarm() {
const res = await fetch('api/alarm/run', {
method: 'POST',
headers: {'Accept': 'application/json'},
});
if (res.status == 200) {
return await res.json();
} else {
throw new Error((await res.json()).errmsg);
}
}
export async function alarmNextTrack() {
const res = await fetch('api/alarm/next', {
method: 'POST',
headers: {'Accept': 'application/json'},
});
if (res.status == 200) {
return await res.json();
} else {
throw new Error((await res.json()).errmsg);
}
}
export async function alarmStop() {
const res = await fetch('api/alarm', {
method: 'DELETE',
headers: {'Accept': 'application/json'},
});
if (res.status == 200) {
return await res.json();
} else {
throw new Error((await res.json()).errmsg);
}
}

View file

@ -5,11 +5,12 @@ export class Settings {
}
}
update({ language, gong_interval, weather_delay, weather_action }) {
update({ language, gong_interval, weather_delay, weather_action, max_run_time }) {
this.language = language;
this.gong_interval = gong_interval;
this.weather_delay = weather_delay;
this.weather_action = weather_action;
this.max_run_time = max_run_time;
}
async save() {

View file

@ -6,20 +6,35 @@
import CycleCounter from '../components/CycleCounter.svelte';
import DateFormat from '../components/DateFormat.svelte';
import { getNextAlarm, newNCyclesAlarm } from '../lib/alarmsingle';
import { isAlarmActive, alarmNextTrack, runAlarm, alarmStop } from '$lib/alarm';
import { getNextAlarm, newNCyclesAlarm } from '$lib/alarmsingle';
import { alarmsSingle } from '../stores/alarmsingle';
import { quotes } from '../stores/quotes';
let nextAlarmP = getNextAlarm();
let isActiveP = isAlarmActive();
function reloadNextAlarm() {
nextAlarmP = getNextAlarm();
alarmsSingle.clear();
}
function reloadIsActiveAlarm() {
isActiveP = isAlarmActive();
return isActiveP;
}
function newCyclesAlarm(ncycles) {
newNCyclesAlarm(ncycles).then(reloadNextAlarm);
}
function stopAlarm() {
alarmStop();
reloadIsActiveAlarm().then((isActive) => {
if (isActive) {
setTimeout(reloadIsActiveAlarm, 10000);
}
})
}
</script>
<Container class="flex-fill d-flex flex-column justify-content-center text-center">
@ -41,6 +56,9 @@
{/if}
<div class="display-5 mb-5">
{#await nextAlarmP}
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
{:then nextalarm}
Prochain réveil&nbsp;:
{#if nextalarm.getDay() == new Date().getDay() && nextalarm.getMonth() == new Date().getMonth() && nextalarm.getFullYear() == new Date().getFullYear()}
@ -62,41 +80,59 @@
{/if}
{/await}
</div>
<div class="d-flex gap-3 justify-content-center">
<a
href="alarms/single/new"
class="btn btn-primary"
>
<Icon name="node-plus" />
Programmer un nouveau réveil
</a>
<button
class="btn btn-info"
on:click={() => newCyclesAlarm(5)}
>
<Icon name="node-plus" />
5 cycles
</button>
<button
class="btn btn-info"
on:click={() => newCyclesAlarm(6)}
>
<Icon name="node-plus" />
6 cycles
</button>
</div>
<div class="d-flex gap-3 mt-3 justify-content-center">
<button class="btn btn-outline-info">
<Icon name="skip-end-fill" />
Chanson suivante
</button>
<button class="btn btn-danger">
<Icon name="stop-circle" />
Éteindre le réveil
</button>
<button class="btn btn-outline-info">
<Icon name="fast-forward-fill" />
Passer cette étape de la routine
</button>
</div>
{#await isActiveP then isActive}
{#if !isActive}
<div class="d-flex gap-3 justify-content-center">
<a
href="alarms/single/new"
class="btn btn-primary"
>
<Icon name="node-plus" />
Programmer un nouveau réveil
</a>
<button
class="btn btn-info"
on:click={() => newCyclesAlarm(5)}
>
<Icon name="node-plus" />
5 cycles
</button>
<button
class="btn btn-info"
on:click={() => newCyclesAlarm(6)}
>
<Icon name="node-plus" />
6 cycles
</button>
<button
class="btn btn-outline-warning"
on:click={() => { runAlarm(); reloadIsActiveAlarm(); }}
>
<Icon name="play-circle" />
Lancer le réveil
</button>
</div>
{:else}
<div class="d-flex gap-3 mt-3 justify-content-center">
<button
class="btn btn-outline-info"
on:click={alarmNextTrack}
>
<Icon name="skip-end-fill" />
Chanson suivante
</button>
<button
class="btn btn-danger"
on:click={stopAlarm}
>
<Icon name="stop-circle" />
Éteindre le réveil
</button>
<button class="btn btn-outline-info">
<Icon name="fast-forward-fill" />
Passer cette étape de la routine
</button>
</div>
{/if}
{/await}
</Container>

View file

@ -95,6 +95,20 @@
<option value="de_DE">Allemand</option>
</Input>
</FormGroup>
<FormGroup>
<Label for="maxRunTime">Durée maximale d'exécution du réveil</Label>
<InputGroup>
<Input
type="number"
id="maxRunTime"
placeholder="60"
bind:value={settings.max_run_time}
on:change={() => settings.save()}
/>
<InputGroupText>min</InputGroupText>
</InputGroup>
</FormGroup>
{/await}
</Form>
</Container>