@@ -1245,7 +1223,6 @@
if (ActiveTab == 'nav-control-tab') {
getTrackProgress();
}
- updateTabStyle();
localStorage.setItem("active-tab", ActiveTab);
});
/* show active / selected subtab */
@@ -1257,7 +1234,6 @@
} else {
document.getElementById("fileOrUrl").required = false;
}
- updateTabStyle();
});
if (host == "") { // Not running on the device -> use the remote host
host = remoteHost;
@@ -1339,8 +1315,13 @@
document.querySelector('#langSel').value = lng;
if (localize) {
localize('body');
+ // (re)initialize all popover buttons to get correct translations in the popovers
+ document.querySelectorAll('[data-bs-toggle="popover"]')
+ .forEach(popoverButton => {
+ new bootstrap.Popover(popoverButton, {html: true, trigger: 'focus'})
+ });
}
- document.querySelector('#menu').classList.remove("show") // Hide the menu again
+ $('#navMenu').removeClass("show"); // Hide the menu again
});
document.querySelector('#langSel').addEventListener('change', (e) => {
const lang = e.target.value;
@@ -1504,6 +1485,7 @@
var data = new FormData(this);
const startTime = new Date().getTime();
let bytesTotal = 0;
+ const fup = $('#firmwareUploadProgress');
$.ajax({
url: '/update',
type: 'POST',
@@ -1536,9 +1518,12 @@
progressText = i18next.t("files.upload.progress", data);
console.log("Percent: " + percent + "%% " + kbps.toFixed(2) + " KB/s");
}
- $("#firmwareUploadProgress").css('width', percent + "%").text(progressText);
+ $(".progress-bar", fup).css('width', percent + "%");
+ $(".label", fup).text(progressText);
}
}, false);
+ fup.addClass('bg-primary bg-opacity-75');
+ $('.progress-bar', fup).removeClass('bg-danger');
return xhr;
},
success: function (data, textStatus, jqXHR) {
@@ -1561,15 +1546,17 @@
}
console.log("Firmware upload success (" + transData.elapsed + ", " + transData.speed + " KB/s): " + textStatus);
const progressText = i18next.t("files.upload.success", transData);
- $("#firmwareUploadProgress").text(progressText);
+ $(".label", fup).text(progressText);
document.getElementById('uploaded_file').value = '';
document.getElementById('uploaded_file_text').innerHTML = '';
restartDevice();
},
- error: function (xhr, status, error) {
- console.log("Firmware upload ERROR: " + xhr.responseText);
- $("#firmwareUploadProgress").html(" " + i18next.t("files.upload.error") + ": " + xhr.responseText + " ");
- toaster.error(i18next.t("files.upload.error") + ": " + xhr.responseText);
+ error: function (request, status, error) {
+ console.log("Firmware upload ERROR!", request);
+ fup.removeClass('bg-primary bg-opacity-75');
+ $('.progress-bar', fup).addClass('bg-danger');
+ $(".label", fup).text(i18next.t("files.upload.error") + ": " + request.statusText);
+ toaster.error(i18next.t("files.upload.error") + ': ' + request.statusText);
}
});
});
@@ -1602,6 +1589,7 @@
}
const startTime = new Date().getTime();
let bytesTotal = 0;
+ const eup = $("#explorerUploadProgress");
$.ajax({
url: '/explorer?path=' + encodeURIComponent(path),
type: 'POST',
@@ -1634,9 +1622,12 @@
progressText = i18next.t("files.upload.progress", data);
console.log("Percent: " + percent + "%% " + kbps.toFixed(2) + " KB/s");
}
- $("#explorerUploadProgress").css('width', percent + "%").text(progressText);
+ $('.progress-bar', eup).css('width', percent + "%");
+ $('.label', eup).text(progressText);
}
}, false);
+ eup.addClass('bg-primary bg-opacity-75');
+ $('.progress-bar', eup).removeClass('bg-danger');
return xhr;
},
success: function (data, textStatus, jqXHR) {
@@ -1659,7 +1650,7 @@
}
console.log("Upload success (" + transData.elapsed + ", " + transData.speed + " KB/s): " + textStatus);
const progressText = i18next.t("files.upload.success", transData);
- $("#explorerUploadProgress").text(progressText);
+ $('.label', eup).text(progressText);
document.getElementById('uploaded_file').value = '';
document.getElementById('uploaded_file_text').innerHTML = '';
getData("http://" + host + "/explorer?path=" + path, function (data) {
@@ -1670,9 +1661,11 @@
});
},
error: function (request, status, error) {
- console.log("Upload ERROR!");
- $("#explorerUploadProgress").html(" " + i18next.t("files.upload.error") + ": " + status + " ");
- toaster.error(i18next.t("files.upload.error") + ": " + status);
+ console.log("Upload ERROR!", request);
+ eup.removeClass('bg-primary bg-opacity-75');
+ $('.progress-bar', eup).addClass('bg-danger');
+ $('.label', eup).text(i18next.t("files.upload.error") + ": " + request.statusText);
+ toaster.error(i18next.t("files.upload.error") + ": " + request.statusText);
}
});
});
@@ -1981,8 +1974,8 @@
console.error('Socket encountered error: ', err.message, 'Closing socket');
};
socket.onmessage = function (event) {
- console.log(event.data);
var socketMsg = JSON.parse(event.data);
+ console.log(socketMsg);
if (socketMsg.rfidId != null) {
document.getElementById('rfidIdMusic').value = socketMsg.rfidId;
toaster.info(i18next.t("toast.rfidDetect", {
@@ -2066,6 +2059,12 @@
$('#maxVolumeSpeaker').bootstrapSlider('setValue', genSettings.maxVolumeSp);
$('#maxVolumeHeadphone').bootstrapSlider('setValue', genSettings.maxVolumeHp);
$('#inactivityTime').bootstrapSlider('setValue', genSettings.sleepInactivity);
+ $('#playMono').prop('checked', genSettings.playMono);
+ $('#savePlayPosShutdown').prop('checked', genSettings.savePosShutdown);
+ $('#savePlayPosRfidChange').prop('checked', genSettings.savePosRfidChg);
+ $('#pauseOnMinVolume').prop('checked', genSettings.pauseOnMinVol);
+ $('#recoverVolBoot').prop('checked', genSettings.recoverVolBoot);
+ $('#volumeCurve').prop('checked', genSettings.volumeCurve > 0);
}
// current values
let currSettings = settings.current;
@@ -2073,29 +2072,6 @@
document.getElementById("rfidIdMusic").value = currSettings.rfidTagId;
volumeSlider.setValue(currSettings.volume);
}
- // default (factory) settings
- let defSettings = settings.defaults;
- if (defSettings) {
- $('#initialVolume').bootstrapSlider('setValue', defSettings.initVolume);
- $('#maxVolumeSpeaker').bootstrapSlider('setValue', defSettings.maxVolumeSp);
- $('#maxVolumeHeadphone').bootstrapSlider('setValue', defSettings.maxVolumeHp);
- $('#inactivityTime').bootstrapSlider('setValue', defSettings.sleepInactivity);
- $('#initBrightness').bootstrapSlider('setValue', defSettings.initBrightness);
- $('#nightBrightness').bootstrapSlider('setValue', defSettings.nightBrightness);
- $('#warningLowVoltage').bootstrapSlider('setValue', defSettings.warnLowVoltage);
- $('#voltageIndicatorLow').bootstrapSlider('setValue', defSettings.indicatorLow);
- $('#voltageIndicatorHigh').bootstrapSlider('setValue', defSettings.indicatorHi);
- $('#voltageCheckInterval').bootstrapSlider('setValue', defSettings.voltageCheckInterval);
- $('#criticalVoltage').bootstrapSlider('setValue', defSettings.criticalVoltage);
- $("#playlistSortMode").val(defSettings.sortMode).change();
- $("#gainLowPass").bootstrapSlider('setValue', defSettings.gainLowPass);
- $("#gainBandPass").bootstrapSlider('setValue', defSettings.gainBandPass);
- $("#gainHighPass").bootstrapSlider('setValue', defSettings.gainHighPass);
- // If there is any better way to overwrite the bootstrap slider tooltip - please change this abdomination!
- formatDBTooltip($('#gainLowPass')[0].previousSibling, defSettings.gainLowPass);
- formatDBTooltip($('#gainBandPass')[0].previousSibling, defSettings.gainBandPass);
- formatDBTooltip($('#gainHighPass')[0].previousSibling, defSettings.gainHighPass);
- }
let eqSettings = settings.equalizer;
if (eqSettings) {
$("#gainLowPass").bootstrapSlider('setValue', eqSettings.gainLowPass);
@@ -2205,18 +2181,12 @@
console.log("comparing ssid vs active:", ssidActive, ssid);
if (ssidActive && ssidActive === ssid) {
ssidElem.classList.add("active");
- } else {
- ssidElem.classList.add("bg-dark");
- ssidElem.classList.add("text-light");
}
let deleteSpan = document.createElement("span");
deleteSpan.classList.add("float-end");
deleteSpan.classList.add("button-group");
let deleteButton = document.createElement("button");
- deleteButton.classList.add("btn");
- deleteButton.classList.add("btn-danger");
- deleteButton.classList.add("fa");
- deleteButton.classList.add("fa-trash");
+ deleteButton.classList.add("btn", "btn-danger", "fa", "fa-trash");
deleteButton.setAttribute("data-bs-toggle", "modal");
deleteButton.setAttribute("data-bs-target", "#deleteSSIDModal");
deleteButton.setAttribute("data-ssid", ssid);
@@ -2398,24 +2368,30 @@
lastIdclicked = clickedId;
var myObj = {
"general": {
- initVolume: Number(document.getElementById('initialVolume').value),
- maxVolumeSp: Number(document.getElementById('maxVolumeSpeaker').value),
- maxVolumeHp: Number(document.getElementById('maxVolumeHeadphone').value),
- sleepInactivity: Number(document.getElementById('inactivityTime').value)
+ initVolume: Number($('#initialVolume').val()),
+ maxVolumeSp: Number($('#maxVolumeSpeaker').val()),
+ maxVolumeHp: Number($('#maxVolumeHeadphone').val()),
+ sleepInactivity: Number($('#inactivityTime').val()),
+ playMono: $('#playMono').prop('checked'),
+ savePosShutdown: $('#savePlayPosShutdown').prop('checked'),
+ savePosRfidChg: $('#savePlayPosRfidChange').prop('checked'),
+ pauseOnMinVol: $('#pauseOnMinVolume').prop('checked'),
+ recoverVolBoot: $('#recoverVolBoot').prop('checked'),
+ volumeCurve: $("#volumeCurve").prop('checked') ? 1 : 0
},
"led": {
- initBrightness: Number(document.getElementById('initBrightness').value),
- nightBrightness: Number(document.getElementById('nightBrightness').value)
+ initBrightness: Number($('#initBrightness').val()),
+ nightBrightness: Number($('#nightBrightness').val())
},
"battery": {
- warnLowVoltage: Number(document.getElementById('warningLowVoltage').value),
- indicatorLow: Number(document.getElementById('voltageIndicatorLow').value),
- indicatorHi: Number(document.getElementById('voltageIndicatorHigh').value),
- criticalVoltage: Number(document.getElementById('criticalVoltage').value),
- voltageCheckInterval: Number(document.getElementById('voltageCheckInterval').value)
+ warnLowVoltage: Number($('#warningLowVoltage').val()),
+ indicatorLow: Number($('#voltageIndicatorLow').val()),
+ indicatorHi: Number($('#voltageIndicatorHigh').val()),
+ criticalVoltage: Number($('#criticalVoltage').val()),
+ voltageCheckInterval: Number($('#voltageCheckInterval').val())
},
"playlist": {
- sortMode: Number(document.getElementById('playlistSortMode').value)
+ sortMode: Number($('#playlistSortMode').val())
}
};
var myJSON = JSON.stringify(myObj);
@@ -2744,25 +2720,6 @@
function formatDBTooltip(target, value) {
target.querySelector('.tooltip-main .tooltip-inner').innerHTML = `${value}`;
}
-
- function updateTabStyle() {
- document.querySelectorAll('.nav-item').forEach((element) => { // Toggle styles
- if (lightSwitch.checked) { // Dark mode
- if (element.classList.contains('active')) {
- element.classList.add('bg-black');
- element.classList.add('text-white');
- } else {
- element.classList.remove('bg-black');
- element.classList.remove('text-white');
- }
- } else { // Light mode
- element.classList.remove('bg-black');
- element.classList.remove('text-white');
- element.classList.remove('bg-white');
- element.classList.remove('text-dark');
- }
- });
- }
$(document).ready(function () {
connect();
buildFileSystemTree("/");
@@ -2837,116 +2794,22 @@
$(function () {
$('[data-bs-toggle="tooltip"]').tooltip();
});
- /* Darkmode Switch with persistence in local storage
- * Copyright: https://www.cssscript.com/dark-mode-switcher-bootstrap-5 */
- let lightSwitch = document.getElementById('lightSwitch');
- if (!lightSwitch) {
- return;
- }
- /**
- * @function darkmode
- * @summary: changes the theme to 'dark mode' and save settings to local storage.
- * Basically, replaces/toggles every CSS class that has '-light' class with '-dark'
- */
- function darkMode() {
- console.log("darkmode");
- $('#explorerTree').jstree("set_theme", "default-dark");
- document.querySelectorAll('.bg-light').forEach((element) => { // Toggle styles
- element.className = element.className.replace(/-light/g, '-temp');
- element.className = element.className.replace(/-dark/g, '-light');
- element.className = element.className.replace(/-temp/g, '-dark');
- });
- document.querySelectorAll('.bg-white').forEach((element) => {
- element.className = element.className.replace(/bg-white/, 'bg-black');
- });
- document.querySelectorAll('.text-dark').forEach((element) => {
- element.className = element.className.replace(/text-dark/, 'text-white');
- });
- document.querySelectorAll('.select-div').forEach((element) => {
- element.setAttribute("data-bs-theme", "dark");
- });
- document.querySelectorAll('.header-nav-element').forEach((element) => {
- element.className = element.className.replace(/text-light/, 'text-dark');
- });
- document.querySelectorAll('.ctrl-button').forEach((element) => {
- element.className = element.className.replace(/text-light/, 'text-dark');
- });
- document.querySelector('.navbar-dark').setAttribute("data-bs-theme", "dark"); // Needed for Langsel
- document.body.classList.add('bg-dark');
- if (document.body.classList.contains('text-dark')) {
- document.body.classList.replace('text-dark', 'text-light');
- } else {
- document.body.classList.add('text-light');
- }
- // Tables
- var tables = document.querySelectorAll('table');
- for (var i = 0; i < tables.length; i++) {
- // add table-dark class to each table
- tables[i].classList.add('table-dark');
- }
- // set light switch input to true
- if (!lightSwitch.checked) {
- lightSwitch.checked = true;
- }
- localStorage.setItem('lightSwitch', 'dark');
- }
- /**
- * @function lightmode
- * @summary: changes the theme to 'light mode' and save settings to local storage.
- */
- function lightMode() {
- console.log("lightmode");
- $('#explorerTree').jstree("set_theme", "default");
- document.querySelectorAll('.bg-dark').forEach((element) => { // Toggle styles
- element.className = element.className.replace(/-dark/g, '-temp');
- element.className = element.className.replace(/-light/g, '-dark');
- element.className = element.className.replace(/-temp/g, '-light');
- });
- document.querySelectorAll('.bg-black').forEach((element) => {
- element.className = element.className.replace(/bg-black/, 'bg-white');
- });
- document.querySelectorAll('.text-white').forEach((element) => {
- element.className = element.className.replace(/text-white/, 'text-dark');
- });
- document.querySelectorAll('.select-div').forEach((element) => {
- element.setAttribute("data-bs-theme", "light");
- });
- document.querySelectorAll('.header-nav-element').forEach((element) => {
- element.className = element.className.replace(/text-dark/, 'text-light');
- });
- document.querySelectorAll('.ctrl-button').forEach((element) => {
- element.className = element.className.replace(/text-light/, 'text-dark');
- });
- document.querySelector('.navbar-dark').setAttribute("data-bs-theme", "light"); // Needed for Langsel
- document.body.classList.add('bg-light');
- if (document.body.classList.contains('text-light')) {
- document.body.classList.replace('text-light', 'text-dark');
- } else {
- document.body.classList.add('text-dark');
- }
- // Tables
- var tables = document.querySelectorAll('table');
- for (var i = 0; i < tables.length; i++) {
- if (tables[i].classList.contains('table-dark')) {
- tables[i].classList.remove('table-dark');
- }
- }
- if (lightSwitch.checked) {
- lightSwitch.checked = false;
- }
- localStorage.setItem('lightSwitch', 'light');
+
+ const lightSwitch = $('#lightSwitch');
+ /* Changes the color mode to a new one and saves the value to local storage. */
+ function newColorMode(mode) {
+ console.log('new mode', mode);
+
+ $('body').attr("data-bs-theme", mode);
+ // File explorer knows 'default' or 'default-dark' as themes
+ $('#explorerTree').jstree('set_theme', mode == 'dark' ? 'default-dark' : 'default');
+
+ localStorage.setItem('lightSwitch', mode);
}
- /**
- * @function onToggleMode
- * @summary: the event handler attached to the switch. calling @darkMode or @lightMode depending on the checked state.
- */
- function onToggleMode() {
- if (lightSwitch.checked) {
- darkMode();
- } else {
- lightMode();
- }
- updateTabStyle();
+
+ /* Triggers a newColorMode(..) call with either 'dark' or 'light' as the new color mode. */
+ function onSwitchDarkMode() {
+ newColorMode(lightSwitch.prop('checked') ? 'dark' : 'light');
}
/**
* @function getSystemDefaultTheme
@@ -2960,16 +2823,11 @@
return 'light';
}
+ /* Fetches the settings for lightSwitch from storage or the system default theme. */
function darkmodeSwitchSetup() {
- var settings = localStorage.getItem('lightSwitch');
- if (settings == null) {
- settings = getSystemDefaultTheme();
- }
- if (settings == 'dark') {
- lightSwitch.checked = true;
- }
- lightSwitch.addEventListener('change', onToggleMode);
- onToggleMode();
+ lightSwitch.prop('checked', (localStorage.getItem('lightSwitch') || getSystemDefaultTheme()) == 'dark');
+ onSwitchDarkMode();
+ lightSwitch.change(onSwitchDarkMode);
}
function selectActiveTabFromLocalStorage() {
@@ -2999,9 +2857,8 @@
}
darkmodeSwitchSetup();
selectActiveTabFromLocalStorage();
- updateTabStyle();
});