design
This commit is contained in:
parent
be7f2b85cb
commit
41828d4905
2347
package-lock.json
generated
2347
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -7,15 +7,18 @@
|
||||
"devDependencies": {
|
||||
"@types/jquery": "^3.5.5",
|
||||
"css-loader": "^5.2.6",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"jquery": "^3.6.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"ts-loader": "^9.2.2",
|
||||
"typescript": "^4.3.2",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.38.0",
|
||||
"webpack-cli": "^4.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/open-sans": "^4.4.2",
|
||||
"http-server": "^0.12.3",
|
||||
"soundcraft-ui-connection": "^0.8.0"
|
||||
}
|
||||
|
BIN
src/background.png
Normal file
BIN
src/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 637 KiB |
BIN
src/hdmi.png
Normal file
BIN
src/hdmi.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
110
src/index.css
110
src/index.css
@ -1,3 +1,4 @@
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@ -8,4 +9,113 @@ html,body {
|
||||
}
|
||||
body {
|
||||
box-sizing: border-box;
|
||||
font-family: 'Open Sans';
|
||||
color: #fff;
|
||||
}
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 30%;
|
||||
background: url('background.png');
|
||||
}
|
||||
.header h1 {
|
||||
margin-top: auto;
|
||||
margin-bottom: 2%;
|
||||
font-size: 3rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content {
|
||||
flex-grow: 1;
|
||||
background-color: #20638f;
|
||||
}
|
||||
.sys-status {
|
||||
margin: 1rem 0 auto 0;
|
||||
}
|
||||
.sys-status #status {
|
||||
font-weight: bolder;
|
||||
color: #6cbe45;
|
||||
}
|
||||
.sys-status #status.disconnected {
|
||||
color: #841212;
|
||||
}
|
||||
.content-inner {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.content-inner .section {
|
||||
margin: 1rem 2rem;
|
||||
}
|
||||
.channel .status {
|
||||
margin-top: 1rem;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.btn-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.btn-group button {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: #040404;
|
||||
border: 0;
|
||||
margin: 0.5rem;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
background-blend-mode: darken;
|
||||
background-size: cover;
|
||||
}
|
||||
.btn-group.btn-mic button {
|
||||
background: linear-gradient(green, green), url('mic.png');
|
||||
}
|
||||
.btn-group.btn-mic button:nth-child(n+2) {
|
||||
background: linear-gradient(#c14a4a, #c14a4a), url('mic.png');
|
||||
}
|
||||
.btn-group.btn-hdmi button {
|
||||
background: linear-gradient(green, green), url('hdmi.png');
|
||||
}
|
||||
.btn-group.btn-hdmi button:nth-child(n+2) {
|
||||
background: linear-gradient(#c14a4a, #c14a4a), url('hdmi.png');
|
||||
}
|
||||
.btn-group.btn-lava button {
|
||||
background: linear-gradient(green, green), url('lava.png');
|
||||
}
|
||||
.btn-group.btn-lava button:nth-child(n+2) {
|
||||
background: linear-gradient(#c14a4a, #c14a4a), url('lava.png');
|
||||
}
|
||||
.fader-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: left;
|
||||
}
|
||||
.fader-group .fader:nth-child(n+2) {
|
||||
margin: auto;
|
||||
}
|
||||
.fader .title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.fader .volume {
|
||||
width: 3rem;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
.footer {
|
||||
background: url('logo.png');
|
||||
width: 128px;
|
||||
height: 104px;
|
||||
margin: auto auto 5% auto;
|
||||
}
|
||||
|
@ -6,6 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div class="wrapper">
|
||||
<section class="header">
|
||||
<h1>Aula helisüsteemi juhtpaneel</h1>
|
||||
</section>
|
||||
<section class="content">
|
||||
<div class="sys-status">Helipuldi staatus: <span id="status"></span></div>
|
||||
<div id="app" class="content-inner"></div>
|
||||
<div class="footer"></div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
84
src/index.ts
84
src/index.ts
@ -1,84 +1,100 @@
|
||||
import { SoundcraftUI } from 'soundcraft-ui-connection';
|
||||
import $ from 'jquery';
|
||||
import '@fontsource/open-sans';
|
||||
import './index.css';
|
||||
|
||||
const HOST = '192.168.0.111';
|
||||
const soundcraft = new SoundcraftUI(HOST);
|
||||
const app = $('#app');
|
||||
const statusText = $('#status');
|
||||
|
||||
// https://github.com/fmalcher/soundcraft-ui/tree/main/packages/mixer-connection
|
||||
|
||||
statusText.text('ÜHENDAMAS');
|
||||
soundcraft.connect();
|
||||
console.log(soundcraft);
|
||||
|
||||
const channels = [
|
||||
{
|
||||
name: 'mikrid 1 ja 2',
|
||||
name: ['MIC 1', 'MIC 2'],
|
||||
channel: [1, 2],
|
||||
separate: true,
|
||||
bothBtn: false,
|
||||
plural: 'Mikrofonid'
|
||||
},
|
||||
{
|
||||
name: 'lava',
|
||||
channel: [5],
|
||||
},
|
||||
{
|
||||
name: 'hdmi',
|
||||
channel: [6],
|
||||
name: ['Lava', 'HDMI'],
|
||||
channel: [5, 6],
|
||||
separate: true,
|
||||
bothBtn: false,
|
||||
},
|
||||
];
|
||||
|
||||
const faders = [
|
||||
{
|
||||
name: ['Lava', 'HDMI'],
|
||||
channel: [5, 6],
|
||||
separate: true
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
const subscriptions: any[] = [];
|
||||
|
||||
function cleanUp(): void {
|
||||
app.empty();
|
||||
subscriptions.forEach((sub) => sub.unsubscribe());
|
||||
subscriptions.splice(0, subscriptions.length);
|
||||
}
|
||||
|
||||
soundcraft.status$.subscribe((status) => {
|
||||
console.log(status);
|
||||
if (status.type !== 'OPEN') {
|
||||
statusText.text('ÜHENDUSETA');
|
||||
statusText.addClass('disconnected');
|
||||
return;
|
||||
}
|
||||
app.empty();
|
||||
statusText.text('ÜHENDUSES');
|
||||
statusText.removeClass('disconnected');
|
||||
cleanUp();
|
||||
channels.forEach((channel) => {
|
||||
const plural = (channel.plural ||
|
||||
(Array.isArray(channel.name) ? channel.name.join(' ja ') : 'kõik'));
|
||||
const managers = channel.channel.map((num) => soundcraft.master.input(num));
|
||||
const statuses = channel.channel.map(() => false);
|
||||
const wrapper = $('<div>').addClass('channel');
|
||||
const statusText = $('<span>').addClass('status');
|
||||
const wrapper = $('<div>').addClass('channel section');
|
||||
const statusText = $('<div>').addClass('status');
|
||||
const btnGroup = $('<div>').addClass('btn-group');
|
||||
const mute = $('<button>').text('välja');
|
||||
const unmute = $('<button>').text('sisse');
|
||||
wrapper.append($('<span>').text(channel.name).addClass('title'));
|
||||
wrapper.append(statusText);
|
||||
// wrapper.append($('<span>').text(channel.name).addClass('title'));
|
||||
if (channel.separate) {
|
||||
wrapper.addClass('separated');
|
||||
channel.channel.forEach((num, index) => {
|
||||
const ibtnGroup = $('<div>').addClass('btn-group');
|
||||
const imute = $('<button>').text(`${index + 1} välja`);
|
||||
const iunmute = $('<button>').text(`${index + 1} sisse`);
|
||||
const name = Array.isArray(channel.name) ? channel.name[index] : index;
|
||||
const ibtnGroup = $('<div>').addClass('btn-group').addClass('btn-' + name.toString().toLowerCase());
|
||||
const imute = $('<button>').text(`${name} välja`.toUpperCase());
|
||||
const iunmute = $('<button>').text(`${name} sisse`.toUpperCase());
|
||||
imute.on('click', () => managers[index].mute());
|
||||
iunmute.on('click', () => managers[index].unmute());
|
||||
ibtnGroup.append(imute, iunmute);
|
||||
ibtnGroup.append(iunmute, imute);
|
||||
wrapper.append(ibtnGroup);
|
||||
});
|
||||
mute.text('mõlemad välja');
|
||||
unmute.text('mõlemad sisse');
|
||||
}
|
||||
channel.channel.forEach((num, index) => {
|
||||
managers[index].mute$.subscribe((status) => {
|
||||
const sub = managers[index].mute$.subscribe((status) => {
|
||||
statuses[index] = status === 1;
|
||||
let text = '';
|
||||
if (channel.separate) {
|
||||
if (statuses.every((stat) => stat === true)) {
|
||||
text = 'kõik on väljas';
|
||||
text = plural + ' on väljas.';
|
||||
} else {
|
||||
const off = statuses.map(
|
||||
(stat, index) => stat ? (index + 1) : false
|
||||
).filter((stat) => stat !== false);
|
||||
(stat, index) => stat ? index : false
|
||||
).filter((stat) => stat !== false) as number[];
|
||||
if (!off.length) {
|
||||
text = 'kõik on sees';
|
||||
text = plural + ' on sees.';
|
||||
} else {
|
||||
text = off.join(', ') + ' on väljas';
|
||||
text = off.map((indx) => channel.name[indx]).join(' ja ') + ' on väljas.';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -86,29 +102,37 @@ soundcraft.status$.subscribe((status) => {
|
||||
}
|
||||
statusText.text(text);
|
||||
});
|
||||
subscriptions.push(sub);
|
||||
});
|
||||
if (channel.bothBtn !== false) {
|
||||
mute.on('click', () => managers.forEach((manager) => manager.mute()));
|
||||
unmute.on('click', () => managers.forEach((manager) => manager.unmute()));
|
||||
btnGroup.append(mute, unmute);
|
||||
btnGroup.append(unmute, mute);
|
||||
wrapper.append(btnGroup);
|
||||
}
|
||||
wrapper.append(statusText);
|
||||
app.append(wrapper);
|
||||
});
|
||||
|
||||
faders.forEach((channel) => {
|
||||
const managers = channel.channel.map((num) => soundcraft.master.input(num));
|
||||
const wrapper = $('<div>').addClass('fader');
|
||||
const wrapper = $('<div>').addClass('fader-group section');
|
||||
channel.channel.forEach((num, index) => {
|
||||
const fader = $('<div>').addClass('fader');
|
||||
const nameText = $('<div>').addClass('title');
|
||||
const statusText = $('<span>').addClass('volume');
|
||||
const input = $('<input>').attr('min', 0).attr('max', 1).attr('step', 0.01).attr('type', 'range');
|
||||
input.on('input', () => {
|
||||
managers[index].setFaderLevel(input.val() as number);
|
||||
});
|
||||
managers[index].faderLevel$.subscribe((level) => {
|
||||
const sub = managers[index].faderLevel$.subscribe((level) => {
|
||||
statusText.text(`${Math.floor(level * 100)}%`);
|
||||
input.val(level);
|
||||
});
|
||||
wrapper.append(statusText);
|
||||
wrapper.append(input);
|
||||
nameText.text((Array.isArray(channel.name) ? channel.name[index] : index) + ' helireguleerimine');
|
||||
fader.append(nameText, statusText, input);
|
||||
wrapper.append(fader);
|
||||
subscriptions.push(sub);
|
||||
});
|
||||
app.append(wrapper);
|
||||
});
|
||||
|
BIN
src/lava.png
Normal file
BIN
src/lava.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
BIN
src/logo.png
Normal file
BIN
src/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
src/mic.png
Normal file
BIN
src/mic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
@ -1,7 +1,7 @@
|
||||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
module.exports = (env, options) => ({
|
||||
entry: './src/index.ts',
|
||||
module: {
|
||||
rules: [
|
||||
@ -14,6 +14,12 @@ module.exports = {
|
||||
test: /\.css$/i,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(woff|woff2|png|jpg)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
@ -29,5 +35,5 @@ module.exports = {
|
||||
template: 'src/index.html'
|
||||
}),
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
};
|
||||
devtool: options.mode != 'production' ? 'eval-source-map' : 'hidden-source-map',
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user