New features
This commit is contained in:
parent
c67b43ab3c
commit
a9c6cdcd0f
16 changed files with 584 additions and 19 deletions
66
ui/src/lib/components/Inputs.svelte
Normal file
66
ui/src/lib/components/Inputs.svelte
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<script>
|
||||
import { activeInputs, inputsList } from '$lib/stores/inputs';
|
||||
import { activeSources } from '$lib/stores/sources';
|
||||
|
||||
export let showInactives = false;
|
||||
</script>
|
||||
|
||||
<ul class="list-group list-group-flush">
|
||||
{#if $activeSources.length === 0 && ((showInactives && $inputsList.length === 0) || (!showInactives && $activeInputs.length === 0))}
|
||||
<li class="list-group-item py-3">
|
||||
<span class="text-muted">
|
||||
Aucune source active.
|
||||
</span>
|
||||
</li>
|
||||
{/if}
|
||||
{#each $activeSources as source}
|
||||
<li class="list-group-item py-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<strong>{source.name}</strong>
|
||||
{#await source.currently()}
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
{:then title}
|
||||
<span class="text-muted">{title}</span>
|
||||
{/await}
|
||||
</div>
|
||||
{#if source.controlable}
|
||||
<div>
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
on:click={() => source.playpause()}
|
||||
>
|
||||
<i class="bi bi-pause"></i>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
{#each $inputsList as input}
|
||||
{#if showInactives || input.active}
|
||||
<li class="list-group-item py-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<strong>{input.name}</strong>
|
||||
{#await input.currently()}
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
{:then title}
|
||||
<span class="text-muted">{title}</span>
|
||||
{/await}
|
||||
</div>
|
||||
{#if input.controlable}
|
||||
<div>
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
on:click={() => input.playpause()}
|
||||
>
|
||||
<i class="bi bi-pause"></i>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
</li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
56
ui/src/lib/input.js
Normal file
56
ui/src/lib/input.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
export class Input {
|
||||
constructor(id, res) {
|
||||
this.id = id;
|
||||
if (res) {
|
||||
this.update(res);
|
||||
}
|
||||
}
|
||||
|
||||
update({ name, active, controlable }) {
|
||||
this.name = name;
|
||||
this.active = active;
|
||||
this.controlable = controlable;
|
||||
}
|
||||
|
||||
async currently() {
|
||||
const data = await fetch(`api/inputs/${this.id}/currently`, {headers: {'Accept': 'application/json'}});
|
||||
if (data.status == 200) {
|
||||
return await data.json();
|
||||
} else {
|
||||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
async playpause() {
|
||||
const data = await fetch(`api/inputs/${this.id}/pause`, {headers: {'Accept': 'application/json'}, method: 'POST'});
|
||||
if (data.status != 200) {
|
||||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getInputs() {
|
||||
const res = await fetch(`api/inputs`, {headers: {'Accept': 'application/json'}})
|
||||
if (res.status == 200) {
|
||||
const data = await res.json();
|
||||
if (data == null) {
|
||||
return {}
|
||||
} else {
|
||||
Object.keys(data).forEach((k) => {
|
||||
data[k] = new Input(k, data[k]);
|
||||
});
|
||||
return data;
|
||||
}
|
||||
} else {
|
||||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getInput(sid) {
|
||||
const res = await fetch(`api/inputs/${sid}`, {headers: {'Accept': 'application/json'}})
|
||||
if (res.status == 200) {
|
||||
return new Input(sid, await res.json());
|
||||
} else {
|
||||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,10 +6,11 @@ export class Source {
|
|||
}
|
||||
}
|
||||
|
||||
update({ name, enabled, active }) {
|
||||
update({ name, enabled, active, controlable }) {
|
||||
this.name = name;
|
||||
this.enabled = enabled;
|
||||
this.active = active;
|
||||
this.controlable = controlable;
|
||||
}
|
||||
|
||||
async activate() {
|
||||
|
|
@ -28,6 +29,13 @@ export class Source {
|
|||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
async playpause() {
|
||||
const data = await fetch(`api/sources/${this.id}/pause`, {headers: {'Accept': 'application/json'}, method: 'POST'});
|
||||
if (data.status != 200) {
|
||||
throw new Error((await res.json()).errmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSources() {
|
||||
|
|
|
|||
41
ui/src/lib/stores/inputs.js
Normal file
41
ui/src/lib/stores/inputs.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { derived, writable } from 'svelte/store';
|
||||
|
||||
import { getInputs } from '$lib/input'
|
||||
|
||||
function createInputsStore() {
|
||||
const { subscribe, set, update } = writable(null);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
|
||||
set: (v) => {
|
||||
update((m) => v);
|
||||
},
|
||||
|
||||
refresh: async () => {
|
||||
const list = await getInputs();
|
||||
update((m) => list);
|
||||
return list;
|
||||
},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export const inputs = createInputsStore();
|
||||
|
||||
export const inputsList = derived(
|
||||
inputs,
|
||||
($inputs) => {
|
||||
if (!$inputs) {
|
||||
return [];
|
||||
}
|
||||
return Object.keys($inputs).map((k) => $inputs[k]);
|
||||
},
|
||||
);
|
||||
|
||||
export const activeInputs = derived(
|
||||
inputsList,
|
||||
($inputsList) => {
|
||||
return $inputsList.filter((s) => s.active);
|
||||
},
|
||||
);
|
||||
|
|
@ -6,6 +6,10 @@
|
|||
sources.refresh();
|
||||
setInterval(sources.refresh, 5000);
|
||||
|
||||
import { inputs } from '$lib/stores/inputs';
|
||||
inputs.refresh();
|
||||
setInterval(inputs.refresh, 4500);
|
||||
|
||||
const version = fetch('api/version', {headers: {'Accept': 'application/json'}}).then((res) => res.json())
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
<script>
|
||||
import Inputs from '$lib/components/Inputs.svelte';
|
||||
import Mixer from '$lib/components/Mixer.svelte';
|
||||
import SourceSelection from '$lib/components/SourceSelection.svelte';
|
||||
import { activeSources } from '$lib/stores/sources';
|
||||
import { activeInputs } from '$lib/stores/inputs';
|
||||
|
||||
let mixerAdvanced = false;
|
||||
</script>
|
||||
|
|
@ -11,7 +13,7 @@
|
|||
</div>
|
||||
|
||||
<div class="container">
|
||||
{#if $activeSources.length === 0}
|
||||
{#if $activeSources.length === 0 && $activeInputs.length === 0}
|
||||
<div class="text-muted text-center mt-1 mb-1">
|
||||
Aucune source active pour l'instant.
|
||||
</div>
|
||||
|
|
@ -21,15 +23,31 @@
|
|||
<div class="d-inline-block me-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<strong>{source.name} :</strong>
|
||||
{#await source.currently()}
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div> <span class="text-muted">@ {source.name}</span>
|
||||
{:then title}
|
||||
{title}
|
||||
<strong>{title}</strong> <span class="text-muted">@ {source.name}</span>
|
||||
{:catch error}
|
||||
activée
|
||||
{source.name} activée
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{#each $activeInputs as input}
|
||||
<div class="d-inline-block me-3">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
{#await input.currently()}
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div> <span class="text-muted">@ {input.name}</span>
|
||||
{:then title}
|
||||
<strong>{title}</strong> <span class="text-muted">@ {input.name}</span>
|
||||
{:catch error}
|
||||
{input.name} activée
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -39,7 +57,7 @@
|
|||
{/if}
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="col-md">
|
||||
<div class="card my-2">
|
||||
<h4 class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
|
|
@ -61,14 +79,13 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="col-md">
|
||||
<div class="card my-2">
|
||||
<h4 class="card-header">
|
||||
<i class="bi bi-speaker"></i>
|
||||
Sources
|
||||
</h4>
|
||||
<div class="card-body">
|
||||
</div>
|
||||
<Inputs />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue