This commit is contained in:
Evert Prants 2021-06-02 15:35:59 +03:00
parent be7f2b85cb
commit 41828d4905
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
11 changed files with 2536 additions and 39 deletions

2347
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,15 +7,18 @@
"devDependencies": { "devDependencies": {
"@types/jquery": "^3.5.5", "@types/jquery": "^3.5.5",
"css-loader": "^5.2.6", "css-loader": "^5.2.6",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.1", "html-webpack-plugin": "^5.3.1",
"jquery": "^3.6.0", "jquery": "^3.6.0",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"ts-loader": "^9.2.2", "ts-loader": "^9.2.2",
"typescript": "^4.3.2", "typescript": "^4.3.2",
"url-loader": "^4.1.1",
"webpack": "^5.38.0", "webpack": "^5.38.0",
"webpack-cli": "^4.7.0" "webpack-cli": "^4.7.0"
}, },
"dependencies": { "dependencies": {
"@fontsource/open-sans": "^4.4.2",
"http-server": "^0.12.3", "http-server": "^0.12.3",
"soundcraft-ui-connection": "^0.8.0" "soundcraft-ui-connection": "^0.8.0"
} }

BIN
src/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

BIN
src/hdmi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,3 +1,4 @@
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -8,4 +9,113 @@ html,body {
} }
body { body {
box-sizing: border-box; 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;
} }

View File

@ -6,6 +6,15 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
</head> </head>
<body> <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> </body>
</html> </html>

View File

@ -1,84 +1,100 @@
import { SoundcraftUI } from 'soundcraft-ui-connection'; import { SoundcraftUI } from 'soundcraft-ui-connection';
import $ from 'jquery'; import $ from 'jquery';
import '@fontsource/open-sans';
import './index.css'; import './index.css';
const HOST = '192.168.0.111'; const HOST = '192.168.0.111';
const soundcraft = new SoundcraftUI(HOST); const soundcraft = new SoundcraftUI(HOST);
const app = $('#app'); const app = $('#app');
const statusText = $('#status');
// https://github.com/fmalcher/soundcraft-ui/tree/main/packages/mixer-connection // https://github.com/fmalcher/soundcraft-ui/tree/main/packages/mixer-connection
statusText.text('ÜHENDAMAS');
soundcraft.connect(); soundcraft.connect();
console.log(soundcraft);
const channels = [ const channels = [
{ {
name: 'mikrid 1 ja 2', name: ['MIC 1', 'MIC 2'],
channel: [1, 2], channel: [1, 2],
separate: true, separate: true,
bothBtn: false,
plural: 'Mikrofonid'
}, },
{ {
name: 'lava', name: ['Lava', 'HDMI'],
channel: [5], channel: [5, 6],
}, separate: true,
{ bothBtn: false,
name: 'hdmi',
channel: [6],
}, },
]; ];
const faders = [ const faders = [
{ {
name: ['Lava', 'HDMI'],
channel: [5, 6], 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) => { soundcraft.status$.subscribe((status) => {
console.log(status); console.log(status);
if (status.type !== 'OPEN') { if (status.type !== 'OPEN') {
statusText.text('ÜHENDUSETA');
statusText.addClass('disconnected');
return; return;
} }
app.empty(); statusText.text('ÜHENDUSES');
statusText.removeClass('disconnected');
cleanUp();
channels.forEach((channel) => { 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 managers = channel.channel.map((num) => soundcraft.master.input(num));
const statuses = channel.channel.map(() => false); const statuses = channel.channel.map(() => false);
const wrapper = $('<div>').addClass('channel'); const wrapper = $('<div>').addClass('channel section');
const statusText = $('<span>').addClass('status'); const statusText = $('<div>').addClass('status');
const btnGroup = $('<div>').addClass('btn-group'); const btnGroup = $('<div>').addClass('btn-group');
const mute = $('<button>').text('välja'); const mute = $('<button>').text('välja');
const unmute = $('<button>').text('sisse'); const unmute = $('<button>').text('sisse');
wrapper.append($('<span>').text(channel.name).addClass('title')); // wrapper.append($('<span>').text(channel.name).addClass('title'));
wrapper.append(statusText);
if (channel.separate) { if (channel.separate) {
wrapper.addClass('separated'); wrapper.addClass('separated');
channel.channel.forEach((num, index) => { channel.channel.forEach((num, index) => {
const ibtnGroup = $('<div>').addClass('btn-group'); const name = Array.isArray(channel.name) ? channel.name[index] : index;
const imute = $('<button>').text(`${index + 1} välja`); const ibtnGroup = $('<div>').addClass('btn-group').addClass('btn-' + name.toString().toLowerCase());
const iunmute = $('<button>').text(`${index + 1} sisse`); const imute = $('<button>').text(`${name} välja`.toUpperCase());
const iunmute = $('<button>').text(`${name} sisse`.toUpperCase());
imute.on('click', () => managers[index].mute()); imute.on('click', () => managers[index].mute());
iunmute.on('click', () => managers[index].unmute()); iunmute.on('click', () => managers[index].unmute());
ibtnGroup.append(imute, iunmute); ibtnGroup.append(iunmute, imute);
wrapper.append(ibtnGroup); wrapper.append(ibtnGroup);
}); });
mute.text('mõlemad välja'); mute.text('mõlemad välja');
unmute.text('mõlemad sisse'); unmute.text('mõlemad sisse');
} }
channel.channel.forEach((num, index) => { channel.channel.forEach((num, index) => {
managers[index].mute$.subscribe((status) => { const sub = managers[index].mute$.subscribe((status) => {
statuses[index] = status === 1; statuses[index] = status === 1;
let text = ''; let text = '';
if (channel.separate) { if (channel.separate) {
if (statuses.every((stat) => stat === true)) { if (statuses.every((stat) => stat === true)) {
text = 'kõik on väljas'; text = plural + ' on väljas.';
} else { } else {
const off = statuses.map( const off = statuses.map(
(stat, index) => stat ? (index + 1) : false (stat, index) => stat ? index : false
).filter((stat) => stat !== false); ).filter((stat) => stat !== false) as number[];
if (!off.length) { if (!off.length) {
text = 'kõik on sees'; text = plural + ' on sees.';
} else { } else {
text = off.join(', ') + ' on väljas'; text = off.map((indx) => channel.name[indx]).join(' ja ') + ' on väljas.';
} }
} }
} else { } else {
@ -86,29 +102,37 @@ soundcraft.status$.subscribe((status) => {
} }
statusText.text(text); statusText.text(text);
}); });
subscriptions.push(sub);
}); });
if (channel.bothBtn !== false) {
mute.on('click', () => managers.forEach((manager) => manager.mute())); mute.on('click', () => managers.forEach((manager) => manager.mute()));
unmute.on('click', () => managers.forEach((manager) => manager.unmute())); unmute.on('click', () => managers.forEach((manager) => manager.unmute()));
btnGroup.append(mute, unmute); btnGroup.append(unmute, mute);
wrapper.append(btnGroup); wrapper.append(btnGroup);
}
wrapper.append(statusText);
app.append(wrapper); app.append(wrapper);
}); });
faders.forEach((channel) => { faders.forEach((channel) => {
const managers = channel.channel.map((num) => soundcraft.master.input(num)); 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) => { channel.channel.forEach((num, index) => {
const fader = $('<div>').addClass('fader');
const nameText = $('<div>').addClass('title');
const statusText = $('<span>').addClass('volume'); const statusText = $('<span>').addClass('volume');
const input = $('<input>').attr('min', 0).attr('max', 1).attr('step', 0.01).attr('type', 'range'); const input = $('<input>').attr('min', 0).attr('max', 1).attr('step', 0.01).attr('type', 'range');
input.on('input', () => { input.on('input', () => {
managers[index].setFaderLevel(input.val() as number); 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)}%`); statusText.text(`${Math.floor(level * 100)}%`);
input.val(level); input.val(level);
}); });
wrapper.append(statusText); nameText.text((Array.isArray(channel.name) ? channel.name[index] : index) + ' helireguleerimine');
wrapper.append(input); fader.append(nameText, statusText, input);
wrapper.append(fader);
subscriptions.push(sub);
}); });
app.append(wrapper); app.append(wrapper);
}); });

BIN
src/lava.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
src/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/mic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,7 +1,7 @@
const path = require('path'); const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = { module.exports = (env, options) => ({
entry: './src/index.ts', entry: './src/index.ts',
module: { module: {
rules: [ rules: [
@ -14,6 +14,12 @@ module.exports = {
test: /\.css$/i, test: /\.css$/i,
use: ['style-loader', 'css-loader'], use: ['style-loader', 'css-loader'],
}, },
{
test: /\.(woff|woff2|png|jpg)$/,
use: {
loader: 'file-loader',
},
},
], ],
}, },
resolve: { resolve: {
@ -29,5 +35,5 @@ module.exports = {
template: 'src/index.html' template: 'src/index.html'
}), }),
], ],
devtool: 'inline-source-map', devtool: options.mode != 'production' ? 'eval-source-map' : 'hidden-source-map',
}; });