mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-12 22:47:15 +03:00
Update webpack and web ui to recent versions, bug fixes
This commit is contained in:
@@ -62,14 +62,15 @@ const nvsTypes = {
|
||||
NVS_TYPE_ANY: 0xff /*! < Must be last */,
|
||||
};
|
||||
const btIcons = {
|
||||
bt_playing: 'play-circle-fill',
|
||||
bt_disconnected: 'bluetooth-fill',
|
||||
bt_neutral: '',
|
||||
bt_connected: 'bluetooth-connect-fill',
|
||||
bt_disabled: '',
|
||||
play_arrow: 'play-circle-fill',
|
||||
pause: 'pause-circle-fill',
|
||||
stop: 'stop-circle-fill',
|
||||
bt_playing: 'media_bluetooth_on',
|
||||
bt_disconnected: 'media_bluetooth_off',
|
||||
bt_neutral: 'bluetooth',
|
||||
bt_connecting: 'bluetooth_searching',
|
||||
bt_connected: 'bluetooth_connected',
|
||||
bt_disabled: 'bluetooth_disabled',
|
||||
play_arrow: 'play_circle_filled',
|
||||
pause: 'pause_circle',
|
||||
stop: 'stop_circle',
|
||||
'': '',
|
||||
};
|
||||
const batIcons = [
|
||||
@@ -80,10 +81,10 @@ const batIcons = [
|
||||
];
|
||||
const btStateIcons = [
|
||||
{ desc: 'Idle', sub: ['bt_neutral'] },
|
||||
{ desc: 'Discovering', sub: ['bt_disconnected'] },
|
||||
{ desc: 'Discovered', sub: ['bt_disconnected'] },
|
||||
{ desc: 'Discovering', sub: ['bt_connecting'] },
|
||||
{ desc: 'Discovered', sub: ['bt_connecting'] },
|
||||
{ desc: 'Unconnected', sub: ['bt_disconnected'] },
|
||||
{ desc: 'Connecting', sub: ['bt_disconnected'] },
|
||||
{ desc: 'Connecting', sub: ['bt_connecting'] },
|
||||
{
|
||||
desc: 'Connected',
|
||||
sub: ['bt_connected', 'play_arrow', 'bt_playing', 'pause', 'stop'],
|
||||
@@ -378,19 +379,18 @@ function handlebtstate(data) {
|
||||
let icon = '';
|
||||
let tt = '';
|
||||
if (data.bt_status !== undefined && data.bt_sub_status !== undefined) {
|
||||
const iconsvg = btStateIcons[data.bt_status].sub[data.bt_sub_status];
|
||||
if (iconsvg) {
|
||||
icon = `#${btIcons[iconsvg]}`;
|
||||
const iconindex = btStateIcons[data.bt_status].sub[data.bt_sub_status];
|
||||
if (iconindex) {
|
||||
icon = btIcons[iconindex];
|
||||
tt = btStateIcons[data.bt_status].desc;
|
||||
} else {
|
||||
icon = `#${btIcons.bt_connected}`;
|
||||
icon = btIcons.bt_connected;
|
||||
tt = 'Output status';
|
||||
}
|
||||
}
|
||||
$('#o_type').title = tt;
|
||||
$('#o_bt').attr('xlink:href',icon);
|
||||
|
||||
|
||||
$('#o_type').attr('title', tt);
|
||||
$('#o_bt').html(icon);
|
||||
}
|
||||
function handleTemplateTypeRadio(outtype) {
|
||||
$('#o_type').children('span').css({ display : 'none' });
|
||||
@@ -466,6 +466,7 @@ let hostName = '';
|
||||
let versionName='Squeezelite-ESP32';
|
||||
let prevmessage='';
|
||||
let project_name=versionName;
|
||||
let board_model='';
|
||||
let platform_name=versionName;
|
||||
let preset_name='';
|
||||
let btSinkNamesOptSel='#cfg-audio-bt_source-sink_name';
|
||||
@@ -549,36 +550,101 @@ function getConfigJson(slimMode) {
|
||||
return config;
|
||||
}
|
||||
|
||||
function handleHWPreset(allfields,reboot){
|
||||
|
||||
const selJson = JSON.parse(allfields[0].value);
|
||||
var cmd=allfields[0].attributes.cmdname.value;
|
||||
|
||||
console.log(`selected model: ${selJson.name}`);
|
||||
let confPayload={
|
||||
timestamp: Date.now(),
|
||||
config : { model_config : {value:selJson.name,type:33 }}
|
||||
};
|
||||
for(const [name, value] of Object.entries(selJson.config)){
|
||||
const storedval=(typeof value === 'string' || value instanceof String)?value:JSON.stringify(value);
|
||||
confPayload.config[name] = {
|
||||
value : storedval,
|
||||
type: 33,
|
||||
}
|
||||
showCmdMessage(
|
||||
cmd,
|
||||
'MESSAGING_INFO',
|
||||
`Setting ${name}=${storedval} `,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
showCmdMessage(
|
||||
cmd,
|
||||
'MESSAGING_INFO',
|
||||
`Committing `,
|
||||
true
|
||||
);
|
||||
$.ajax({
|
||||
url: '/config.json',
|
||||
dataType: 'text',
|
||||
method: 'POST',
|
||||
cache: false,
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify(confPayload),
|
||||
error: function(xhr, _ajaxOptions, thrownError){
|
||||
handleExceptionResponse(xhr, _ajaxOptions, thrownError);
|
||||
showCmdMessage(
|
||||
cmd,
|
||||
'MESSAGING_ERROR',
|
||||
`Unexpected error ${(thrownError !== '')?thrownError:'with return status = '+xhr.status} `,
|
||||
true
|
||||
);
|
||||
},
|
||||
success: function(response) {
|
||||
showCmdMessage(
|
||||
cmd,
|
||||
'MESSAGING_INFO',
|
||||
`Saving complete `,
|
||||
true
|
||||
);
|
||||
console.log(response);
|
||||
if (reboot) {
|
||||
delayReboot(2500, cmd);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// pull json file from https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json and
|
||||
// load the names into cfg-hw-preset-model_name
|
||||
function loadPresets() {
|
||||
if($("#cfg-hw-preset-model_config").length == 0) return;
|
||||
if(presetsloaded) return;
|
||||
presetsloaded = true;
|
||||
$('#cfg-hw-preset-model_config').html('<option>--</option>');
|
||||
$.getJSON(
|
||||
'https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/b462691f69e2ad31ac95c547af6ec97afb0f53db/squeezelite-esp32-presets.json',
|
||||
'https://gist.githubusercontent.com/sle118/dae585e157b733a639c12dc70f0910c5/raw/',
|
||||
{_: new Date().getTime()},
|
||||
function(data) {
|
||||
$.each(data, function(key, val) {
|
||||
$('#cfg-hw-preset-model_config').append(`<option value="${JSON.stringify(val).replace(/\"/g, '\'')}">${val.name}</option>`);
|
||||
$('#cfg-hw-preset-model_config').append(`<option value='${JSON.stringify(val).replace(/"/g, '\"').replace(/\'/g, '\"')}'>${val.name}</option>`);
|
||||
if(preset_name !=='' && preset_name==val.name){
|
||||
$('#cfg-hw-preset-model_config').val(preset_name);
|
||||
}
|
||||
});
|
||||
if(preset_name !== ''){
|
||||
('#prev_preset').show().val(preset_name);
|
||||
}
|
||||
console.log('update prev_preset in case of a change');
|
||||
}
|
||||
}
|
||||
|
||||
).fail(function(jqxhr, textStatus, error) {
|
||||
const err = textStatus + ', ' + error;
|
||||
console.log('Request Failed: ' + err);
|
||||
$('hw-preset-section').hide();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function delayReboot(duration, cmdname, ota = 'reboot') {
|
||||
const url = '/'+ota+'.json';
|
||||
$('tbody#tasks').empty();
|
||||
@@ -736,9 +802,6 @@ window.handleConnect = function(){
|
||||
|
||||
}
|
||||
$(document).ready(function() {
|
||||
$('#wifiTable').on('click','tr', function() {
|
||||
|
||||
});
|
||||
$('#fw-url-input').on('input', function() {
|
||||
if($(this).val().length>8 && ($(this).val().startsWith('http://') || $(this).val().startsWith('https://'))){
|
||||
$('#start-flash').show();
|
||||
@@ -890,12 +953,6 @@ $(document).ready(function() {
|
||||
$('*[href*="-nvs"]').hide();
|
||||
}
|
||||
});
|
||||
$('#btn-save-cfg-hw-preset').on('click', function(){
|
||||
runCommand(this,false);
|
||||
});
|
||||
$('#btn-commit-cfg-hw-preset').on('click', function(){
|
||||
runCommand(this,true);
|
||||
});
|
||||
$('#btn_reboot_recovery').on('click',function(){
|
||||
handleReboot('recovery');
|
||||
});
|
||||
@@ -1192,15 +1249,11 @@ function formatAP(ssid, rssi, auth){
|
||||
return `<tr data-toggle="modal" data-target="#WifiConnectDialog"><td></td><td>${ssid}</td><td>
|
||||
<span class="material-icons" style="fill:white; display: inline" >${rssiToIcon(rssi)}</span>
|
||||
</td><td>
|
||||
<svg style="fill:white; width:1.5rem; height: 1.5rem;">
|
||||
<use xlink:href="#lock${(auth == 0 ? '-unlock':'')}-fill"></use>
|
||||
</svg>
|
||||
|
||||
<span class="material-icons">${(auth == 0 ? 'no_encryption':'lock')}</span>
|
||||
</td></tr>`;
|
||||
}
|
||||
function refreshAPHTML2(data) {
|
||||
let h = '';
|
||||
$('#tab-wifi').show();
|
||||
$('#wifiTable tr td:first-of-type').text('');
|
||||
$('#wifiTable tr').removeClass('table-success table-warning');
|
||||
if(data){
|
||||
@@ -1221,8 +1274,7 @@ function refreshAPHTML2(data) {
|
||||
$(wifiSelector).filter(function() {return $(this).text() === ConnectedTo.ssid; }).siblings().first().html('✓').parent().addClass((ConnectedTo.urc === connectReturnCode.OK?'table-success':'table-warning'));
|
||||
$('span#foot-if').html(`SSID: <strong>${ConnectedTo.ssid}</strong>, IP: <strong>${ConnectedTo.ip}</strong>`);
|
||||
$('#wifiStsIcon').html(rssiToIcon(ConnectedTo.rssi));
|
||||
$(".if_eth").hide();
|
||||
$('.if_wifi').show();
|
||||
|
||||
}
|
||||
else if(ConnectedTo.urc !== connectReturnCode.ETH){
|
||||
$('span#foot-if').html('');
|
||||
@@ -1230,9 +1282,7 @@ function refreshAPHTML2(data) {
|
||||
|
||||
}
|
||||
function refreshETH() {
|
||||
|
||||
$(".if_eth").show();
|
||||
$('.if_wifi').hide();
|
||||
|
||||
if(ConnectedTo.urc === connectReturnCode.ETH ){
|
||||
$('span#foot-if').html(`Network: Ethernet, IP: <strong>${ConnectedTo.ip}</strong>`);
|
||||
}
|
||||
@@ -1496,13 +1546,17 @@ function handleWifiDialog(data){
|
||||
}
|
||||
}
|
||||
function handleNetworkStatus(data) {
|
||||
if(hasConnectionChanged(data)){
|
||||
if(hasConnectionChanged(data) || !data.urc){
|
||||
ConnectedTo=data;
|
||||
if(ConnectedTo.urc == connectReturnCode.ETH ){
|
||||
refreshETH();
|
||||
$(".if_eth").hide();
|
||||
$('.if_wifi').hide();
|
||||
if(!data.urc || ConnectedTo.urc == connectReturnCode.ETH ){
|
||||
$('.if_wifi').show();
|
||||
refreshAPHTML2();
|
||||
}
|
||||
else {
|
||||
refreshAPHTML2();
|
||||
$(".if_eth").show();
|
||||
refreshETH();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1546,15 +1600,18 @@ function checkStatus() {
|
||||
ota_dsc: (data.ota_dsc ??''),
|
||||
event: flash_events.PROCESS_OTA_STATUS
|
||||
});
|
||||
|
||||
if (data.project_name && data.project_name !== '') {
|
||||
project_name = data.project_name;
|
||||
}
|
||||
if(data.platform_name && data.platform_name!==''){
|
||||
platform_name = data.platform_name;
|
||||
}
|
||||
if(board_model==='') board_model = project_name;
|
||||
if(board_model==='') board_model = 'Squeezelite-ESP32';
|
||||
if (data.version && data.version !== '') {
|
||||
versionName=data.version;
|
||||
$("#navtitle").html(`${project_name}${recovery?'<br>[recovery]':''}`);
|
||||
$("#navtitle").html(`${board_model}${recovery?'<br>[recovery]':''}`);
|
||||
$('span#foot-fw').html(`fw: <strong>${versionName}</strong>, mode: <strong>${recovery?"Recovery":project_name}</strong>`);
|
||||
} else {
|
||||
$('span#flash-status').html('');
|
||||
@@ -1614,38 +1671,41 @@ window.runCommand = function(button, reboot) {
|
||||
false
|
||||
);
|
||||
const fields = document.getElementById('flds-' + cmdstring);
|
||||
const allfields = fields?.querySelectorAll('select,input');
|
||||
if(cmdstring ==='cfg-hw-preset') return handleHWPreset(allfields,reboot);
|
||||
cmdstring += ' ';
|
||||
if (fields) {
|
||||
const allfields = fields.querySelectorAll('select,input');
|
||||
for (var i = 0; i < allfields.length; i++) {
|
||||
const attr = allfields[i].attributes;
|
||||
|
||||
for(const field of allfields) {
|
||||
let qts = '';
|
||||
let opt = '';
|
||||
let isSelect = $(allfields[i]).is('select');
|
||||
const hasValue=attr.hasvalue.value === 'true';
|
||||
const validVal=(isSelect && allfields[i].value !== '--' ) || ( !isSelect && allfields[i].value !== '' );
|
||||
let attr=field.attributes;
|
||||
let isSelect = $(field).is('select');
|
||||
const hasValue=attr?.hasvalue?.value === 'true';
|
||||
const validVal=(isSelect && field.value !== '--' ) || ( !isSelect && field.value !== '' );
|
||||
|
||||
if ( !hasValue|| hasValue && validVal) {
|
||||
if (attr.longopts.value !== 'undefined') {
|
||||
opt += '--' + attr.longopts.value;
|
||||
} else if (attr.shortopts.value !== 'undefined') {
|
||||
if (attr?.longopts?.value !== 'undefined') {
|
||||
opt += '--' + attr?.longopts?.value;
|
||||
} else if (attr?.shortopts?.value !== 'undefined') {
|
||||
opt = '-' + attr.shortopts.value;
|
||||
}
|
||||
|
||||
if (attr.hasvalue.value === 'true') {
|
||||
if (allfields[i].value !== '') {
|
||||
qts = /\s/.test(allfields[i].value) ? '"' : '';
|
||||
cmdstring += opt + ' ' + qts + allfields[i].value + qts + ' ';
|
||||
if (attr?.hasvalue?.value === 'true') {
|
||||
if (attr?.value !== '') {
|
||||
qts = /\s/.test(field.value) ? '"' : '';
|
||||
cmdstring += opt + ' ' + qts + field.value + qts + ' ';
|
||||
}
|
||||
} else {
|
||||
// this is a checkbox
|
||||
if (allfields[i].checked) {
|
||||
if (field?.checked) {
|
||||
cmdstring += opt + ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(cmdstring);
|
||||
|
||||
const data = {
|
||||
@@ -1705,13 +1765,7 @@ function getCommands() {
|
||||
const isConfig = cmdParts[0] === 'cfg';
|
||||
const targetDiv = '#tab-' + cmdParts[0] + '-' + cmdParts[1];
|
||||
let innerhtml = '';
|
||||
|
||||
// innerhtml+='<tr class="table-light"><td>'+(isConfig?'<h1>':'');
|
||||
innerhtml +=
|
||||
'<div class="card text-white mb-3"><div class="card-header">' +
|
||||
command.help.encodeHTML().replace(/\n/g, '<br />') +
|
||||
'</div><div class="card-body">';
|
||||
innerhtml += '<fieldset id="flds-' + command.name + '">';
|
||||
innerhtml += `<div class="card text-white mb-3"><div class="card-header">${command.help.encodeHTML().replace(/\n/g, '<br />')}</div><div class="card-body"><fieldset id="flds-${command.name}">`;
|
||||
if (command.argtable) {
|
||||
command.argtable.forEach(function(arg) {
|
||||
let placeholder = arg.datatype || '';
|
||||
@@ -1719,8 +1773,6 @@ function getCommands() {
|
||||
const curvalue = getLongOps(data,command.name,arg.longopts);
|
||||
|
||||
let attributes = 'hasvalue=' + arg.hasvalue + ' ';
|
||||
|
||||
// attributes +='datatype="'+arg.datatype+'" ';
|
||||
attributes += 'longopts="' + arg.longopts + '" ';
|
||||
attributes += 'shortopts="' + arg.shortopts + '" ';
|
||||
attributes += 'checkbox=' + arg.checkbox + ' ';
|
||||
@@ -1738,25 +1790,9 @@ function getCommands() {
|
||||
attributes += ' style="visibility: hidden;"';
|
||||
}
|
||||
if (arg.checkbox) {
|
||||
innerhtml +=
|
||||
'<div class="form-check"><label class="form-check-label">';
|
||||
innerhtml +=
|
||||
'<input type="checkbox" ' +
|
||||
attributes +
|
||||
' class="form-check-input ' +
|
||||
extraclass +
|
||||
'" value="" >' +
|
||||
arg.glossary.encodeHTML() +
|
||||
'<small class="form-text text-muted">Previous value: ' +
|
||||
(curvalue ? 'Checked' : 'Unchecked') +
|
||||
'</small></label>';
|
||||
innerhtml += `<div class="form-check"><label class="form-check-label"><input type="checkbox" ${attributes} class="form-check-input ${extraclass}" value="" >${arg.glossary.encodeHTML()}<small class="form-text text-muted">Previous value: ${(curvalue ? 'Checked' : 'Unchecked')}</small></label>`;
|
||||
} else {
|
||||
innerhtml +=
|
||||
'<div class="form-group" ><label for="' +
|
||||
ctrlname +
|
||||
'">' +
|
||||
arg.glossary.encodeHTML() +
|
||||
'</label>';
|
||||
innerhtml +=`<div class="form-group" ><label for="${ctrlname}">${arg.glossary.encodeHTML()}</label>`;
|
||||
if (placeholder.includes('|')) {
|
||||
extraclass = placeholder.startsWith('+') ? ' multiple ' : '';
|
||||
placeholder = placeholder
|
||||
@@ -1770,54 +1806,23 @@ function getCommands() {
|
||||
});
|
||||
innerhtml += '</select>';
|
||||
} else {
|
||||
innerhtml +=
|
||||
'<input type="text" class="form-control ' +
|
||||
extraclass +
|
||||
'" placeholder="' +
|
||||
placeholder +
|
||||
'" ' +
|
||||
attributes +
|
||||
'>';
|
||||
innerhtml +=`<input type="text" class="form-control ${extraclass}" placeholder="${placeholder}" ${attributes}>`;
|
||||
}
|
||||
innerhtml +=
|
||||
'<small class="form-text text-muted">Previous value: ' +
|
||||
(curvalue || '') +
|
||||
'</small>';
|
||||
innerhtml +=`<small class="form-text text-muted">Previous value: ${(curvalue || '')}</small>`;
|
||||
}
|
||||
innerhtml += '</div>';
|
||||
});
|
||||
}
|
||||
innerhtml += '<div style="margin-top: 16px;">';
|
||||
innerhtml +=
|
||||
'<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true" style="display: none;" id="toast_' +
|
||||
command.name +
|
||||
'">';
|
||||
innerhtml +=
|
||||
'<div class="toast-header"><strong class="mr-auto">Result</strong><button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close" onclick="$(this).parent().parent().hide()">';
|
||||
innerhtml +=
|
||||
'<span aria-hidden="true">×</span></button></div><div class="toast-body" id="msg_' +
|
||||
command.name +
|
||||
'"></div></div>';
|
||||
innerhtml += `<div style="margin-top: 16px;">
|
||||
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true" style="display: none;" id="toast_${command.name}">
|
||||
<div class="toast-header"><strong class="mr-auto">Result</strong><button type="button" class="ml-2 mb-1 close click_to_close" data-dismiss="toast" aria-label="Close" >
|
||||
<span aria-hidden="true">×</span></button></div><div class="toast-body" id="msg_${command.name}"></div></div>`;
|
||||
if (isConfig) {
|
||||
innerhtml +=
|
||||
'<button type="submit" class="btn btn-info" id="btn-save-' +
|
||||
command.name +
|
||||
'" cmdname="' +
|
||||
command.name +
|
||||
'" onclick="runCommand(this,false)">Save</button>';
|
||||
innerhtml +=
|
||||
'<button type="submit" class="btn btn-warning" id="btn-commit-' +
|
||||
command.name +
|
||||
'" cmdname="' +
|
||||
command.name +
|
||||
'" onclick="runCommand(this,true)">Apply</button>';
|
||||
`<button type="submit" class="btn btn-info sclk" id="btn-save-${command.name}" cmdname="${command.name}">Save</button>
|
||||
<button type="submit" class="btn btn-warning cclk" id="btn-commit-${command.name}" cmdname="${command.name}">Apply</button>`;
|
||||
} else {
|
||||
innerhtml +=
|
||||
'<button type="submit" class="btn btn-success" id="btn-run-' +
|
||||
command.name +
|
||||
'" cmdname="' +
|
||||
command.name +
|
||||
'" onclick="runCommand(this,false)">Execute</button>';
|
||||
innerhtml +=`<button type="submit" class="btn btn-success sclk" id="btn-run-${command.name}" cmdname="${command.name}">Execute</button>`;
|
||||
}
|
||||
innerhtml += '</div></fieldset></div></div>';
|
||||
if (isConfig) {
|
||||
@@ -1827,7 +1832,9 @@ function getCommands() {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(".click_to_close").on('click', function(){$(this).parent().parent().hide()});
|
||||
$(".sclk").on('click',function(){runCommand(this,false);});
|
||||
$(".cclk").on('click',function(){runCommand(this,true);});
|
||||
data.commands.forEach(function(command) {
|
||||
$('[cmdname=' + command.name + ']:input').val('');
|
||||
$('[cmdname=' + command.name + ']:checkbox').prop('checked', false);
|
||||
@@ -1861,7 +1868,6 @@ function getCommands() {
|
||||
else {
|
||||
handleExceptionResponse(xhr, ajaxOptions, thrownError);
|
||||
}
|
||||
|
||||
$('#commands-list').empty();
|
||||
blockAjax = false;
|
||||
});
|
||||
@@ -1911,7 +1917,9 @@ function getConfig() {
|
||||
else if (key == 'preset_name') {
|
||||
preset_name = val;
|
||||
}
|
||||
|
||||
else if (key=='board_model') {
|
||||
board_model=val;
|
||||
}
|
||||
|
||||
$('tbody#nvsTable').append(
|
||||
'<tr>' +
|
||||
|
||||
Reference in New Issue
Block a user