2024-03-26 11:23:59 +00:00
<!doctype html>
< html >
< head >
< meta charset = 'utf-8' >
< meta name = 'viewport' content = 'width=device-width,initial-scale=1' >
2024-03-26 12:33:47 +00:00
< title > NetSpeaker Demo (on [IP here])< / title >
2024-03-26 11:23:59 +00:00
< link href = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css' rel = 'stylesheet'
integrity='sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN' crossorigin='anonymous'>
< style > # playbackMuteButton : hover { background-color : #000000 00 ; } < / style >
< / head >
< body data-bs-theme = 'dark' >
2024-03-26 16:00:14 +00:00
< div class = 'text-center container-sm placeholder-glow' style = 'padding: 4em 0em' >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
< p > Welcome to< / p >
2024-03-26 16:00:14 +00:00
< h1 id = 'updatedLabel_FRNAME_title' > < span class = "placeholder col-3" > < / span > < / h1 >
< p id = "title_onIP" > < span class = "placeholder col-1" > < / span > < / p >
2024-03-26 17:02:24 +00:00
< p style = 'font-size: .875em; color: var(--bs-code-color); padding-top: .5rem' id = "updatedLabel_VERSION_title" > < span
class="placeholder col-2">< / span > < / p >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
< hr style = 'margin: 3em 0em;' >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - -
---- INFORMATIONS ACCORDION ---
------------------------------>
< div class = 'accordion text-start' id = 'accordion-info' >
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse' data-bs-target = '#accordion-info-playback'
aria-expanded='true' aria-controls='accordion-info-playback'>
Playback information
< / button >
< / h2 >
< div id = 'accordion-info-playback' class = 'accordion-collapse collapse' data-bs-parent = '#accordion-info' >
< div class = 'accordion-body' >
< table class = 'table table-striped' >
< tbody >
< tr >
< td > Playing< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_PLAYING_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Volume< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_VOLUME_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Muted< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_MUTED_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Equalizer Low< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_EQLOW_table_top" > < span class = "placeholder col-12" > < / span > < / td >
< / tr >
2024-03-26 11:23:59 +00:00
< tr >
< td > Equalizer Mid< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_EQMID_table_top" > < span class = "placeholder col-12" > < / span > < / td >
< / tr >
2024-03-26 11:23:59 +00:00
< tr >
< td > Equalizer High< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_EQHIGH_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Balance (range -16 | +16)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_BALANCE_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Path to playlist< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_PLPATH_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Index in playlist (starting from 0)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_PLIDX_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource path< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_PATH_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource type< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_TYPE_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource title< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_TITLE_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource album< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_ALBUM_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource artist< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_ARTIST_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource track number< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_TRACKNR_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource year< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_YEAR_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource genre< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_GENRE_table_top" > < span class = "placeholder col-12" > < / span > < / td >
< / tr >
< tr >
< td > Resource copyright< / td >
< td class = 'text-end' id = "updatedLabel_RS_COPYRIGHT_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Resource language (for TTS)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = "updatedLabel_RS_LANGUAGE_table_top" > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< / tbody >
< / table >
< / div >
< / div >
< / div >
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse' data-bs-target = '#accordion-info-general'
aria-expanded='true' aria-controls='accordion-info-general'>
General information
< / button >
< / h2 >
< div id = 'accordion-info-general' class = 'accordion-collapse collapse' data-bs-parent = '#accordion-info' >
< div class = 'accordion-body' >
< table class = 'table table-striped' >
< tbody >
< tr >
< td > Version< / td >
2024-03-26 16:00:14 +00:00
< td class = 'text-end' id = "updatedLabel_VERSION_table" > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Friendly name< / td >
2024-03-26 16:00:14 +00:00
< td class = 'text-end' id = "updatedLabel_FRNAME_table" > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Save & Restore state< / td >
2024-03-26 16:00:14 +00:00
< td class = 'text-end' id = "updatedLabel_RESTORESTATE_table" > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Save & Restore playing state (default no)< / td >
2024-03-26 16:00:14 +00:00
< td class = 'text-end' id = "updatedLabel_RESTOREPLAYING_table" > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > WiFi SSID< / td >
2024-03-26 16:00:14 +00:00
< td class = 'text-end' id = "updatedLabel_WIFISSID_table" > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
2024-03-26 18:25:17 +00:00
< tr >
< td > AP SSID< / td >
< td class = 'text-end' id = "updatedLabel_APSSID_table" > < span class = "placeholder col-4" > < / span > < / td >
< / tr >
< tr >
< td > AP PSK< / td >
< td class = 'text-end' id = "updatedLabel_APPSK_table" > < span class = "placeholder col-4" > < / span > < / td >
< / tr >
2024-03-26 11:23:59 +00:00
< / tbody >
< / table >
< / div >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
< hr style = 'margin: 3em 0em;' >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- - - API FUNCTIONS ACCODRION - - -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
< div class = 'accordion text-start' id = 'accordion' >
2024-03-26 17:02:24 +00:00
<!-- PLAYBACK Collapsible -->
2024-03-26 11:23:59 +00:00
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse'
data-bs-target='#accordion-collapse-playback' aria-expanded='true' aria-controls='accordion-collapse-playback'>
Playback
< span class = 'badge text-bg-success' > /api/v1/playback/< / span >
< span class = 'badge text-bg-info' > /api/v1/volume/< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-playback' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< table class = 'table table-striped' >
< tbody >
< tr >
< td > Playing< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_PLAYING_table_bottom' > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Volume< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_VOLUME_table_bottom' > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Muted< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_MUTED_table_bottom' > < span class = "placeholder col-4" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< / tbody >
< / table >
< hr >
< div class = 'btn-group' role = 'group' aria-label = 'Basic playback option (play, pause, next, previous)' >
< button type = 'button' class = 'btn btn-secondary' onclick = "http
2024-03-26 18:18:03 +00:00
= new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/playback/previous');http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< svg xmlns = 'http://www.w3.org/2000/svg' width = '16' height = '16' fill = 'currentColor' class = 'bi bi-rewind-circle'
viewBox='0 0 16 16'>
< path d = 'M7.729 5.055a.5.5 0 0 0-.52.038l-3.5 2.5a.5.5 0 0 0 0 .814l3.5 2.5A.5.5 0 0 0 8 10.5V8.614l3.21 2.293A.5.5 0 0 0 12 10.5v-5a.5.5 0 0 0-.79-.407L8 7.386V5.5a.5.5 0 0 0-.271-.445' / >
< path d = 'M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8' / >
< / svg >
< / button >
< button type = 'button' class = 'btn btn-success' onclick = "http
2024-03-26 18:18:03 +00:00
= new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/playback/play');http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< svg xmlns = 'http://www.w3.org/2000/svg' width = '16' height = '16' fill = 'currentColor' class = 'bi bi-play-circle'
viewBox='0 0 16 16'>
< path d = 'M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16' > < / path >
< path d = 'M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .814l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445' > < / path >
< / svg >
< / button >
2024-03-26 18:18:03 +00:00
< button type = 'button' class = 'btn btn-success' onclick = "http
= new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/playback/pause');http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< svg xmlns = 'http://www.w3.org/2000/svg' width = '16' height = '16' fill = 'currentColor' class = 'bi bi-pause-circle'
viewBox='0 0 16 16'>
< path d = 'M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16' / >
< path d = 'M5 6.25a1.25 1.25 0 1 1 2.5 0v3.5a1.25 1.25 0 1 1-2.5 0zm3.5 0a1.25 1.25 0 1 1 2.5 0v3.5a1.25 1.25 0 1 1-2.5 0z' / >
< / svg >
< / button >
< button type = 'button' class = 'btn btn-secondary'
2024-03-26 18:18:03 +00:00
onclick="http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/playback/next');http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< svg xmlns = 'http://www.w3.org/2000/svg' width = '16' height = '16' fill = 'currentColor'
class='bi bi-skip-forward-circle'
viewBox='0 0 16 16'>
< path d = 'M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16' / >
< path d = 'M4.271 5.055a.5.5 0 0 1 .52.038L7.5 7.028V5.5a.5.5 0 0 1 .79-.407L11 7.028V5.5a.5.5 0 0 1 1 0v5a.5.5 0 0 1-1 0V8.972l-2.71 1.935a.5.5 0 0 1-.79-.407V8.972l-2.71 1.935A.5.5 0 0 1 4 10.5v-5a.5.5 0 0 1 .271-.445' / >
< / svg >
< / button >
< / div >
< br >
< hr >
< br > < label for = 'volumeRange' class = 'form-label' > Volume< / label >
2024-03-26 18:18:03 +00:00
< input type = 'range' class = 'form-range' value = '0' min = '0' max = '0'
id='updatedLabel_VOLUME_range_bottom'
onchange="http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/volume/' + this.value);http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< button type = 'button' id = 'playbackMuteButton' onclick =
2024-03-26 18:18:03 +00:00
"http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/volume/toggle_mute');http.send();updateStrings();"
class='btn btn-danger'>
2024-03-26 11:23:59 +00:00
< svg xmlns = 'http://www.w3.org/2000/svg' width = '16' height = '16' fill = 'currentColor' class = 'bi bi-volume-mute'
viewBox='0 0 16 16'>
< path d = 'M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06zM6 5.04 4.312 6.39A.5.5 0 0 1 4 6.5H2v3h2a.5.5 0 0 1 .312.11L6 10.96zm7.854.606a.5.5 0 0 1 0 .708L12.207 8l1.647 1.646a.5.5 0 0 1-.708.708L11.5 8.707l-1.646 1.647a.5.5 0 0 1-.708-.708L10.793 8 9.146 6.354a.5.5 0 1 1 .708-.708L11.5 7.293l1.646-1.647a.5.5 0 0 1 .708 0z' > < / path >
< / svg >
Mute/Unmute
< / button >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
<!-- PLAYLIST Collapsible -->
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse'
data-bs-target='#accordion-collapse-playlist' aria-expanded='true' aria-controls='accordion-collapse-playlist'>
Playlist
< span class = 'badge text-bg-success' > /api/v1/playlist/< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-playlist' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
<!-- play playlist (select playlist) api demo -->
< p > Demo for playing a specific playlist on the SD card over the API.< / p >
< div class = 'input-group mb-3' >
< input type = 'text' class = 'form-control' placeholder = 'Playlist path (must start with a /)'
aria-label='Playlist path (must start with a /)' aria-describedby='playlist_playBtn'
id='playlist_playPathInput'>
< button class = 'btn btn-success' type = 'button' id = 'playlist_playBtn' onclick =
2024-03-26 18:18:03 +00:00
"playlistPath = document.getElementById('playlist_playPathInput').value;
http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/playlist/play?playlist_path='+playlistPath);http.send();
updateStrings();">
2024-03-26 11:23:59 +00:00
Change
< / button >
< / div >
< hr >
2024-03-26 18:18:03 +00:00
<!-- Create playlist api demo -->
2024-03-26 11:23:59 +00:00
< p > Demo for creating a new playlist containing all the contents of the given folder (on the SD card).< / p >
< p > The new playlist will be located in the given folder and is named < code > .directory.m3u< / code > . This can't be changed.
< / p >
< p > Creating fully personalized playlist or even uploading one will be subject of further development (see also the
Roadmap of the NetSpeaker project!).< / p >
< div class = 'input-group mb-3' >
< input type = 'text' class = 'form-control' placeholder = 'Folder path (must start with and end without a /)'
aria-label='Folder path (must start with a /)' aria-describedby='playlist_createBtn'
id='playlist_createPathInput'>
< button class = 'btn btn-success' type = 'button' id = 'playlist_createBtn' onclick =
2024-03-26 18:18:03 +00:00
"folderPath = document.getElementById('playlist_createPathInput').value;
http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/playlist/create?folder_path='+folderPath);http.send();
updateStrings();">
2024-03-26 11:23:59 +00:00
Change
< / button >
< / div >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
<!-- BALANCE Collapsible -->
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse'
data-bs-target='#accordion-collapse-balance' aria-expanded='true' aria-controls='accordion-collapse-balance'>
Balance
< span class = 'badge text-bg-info' > /api/v1/balance/< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-balance' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< p > The Audio library used maps -16 to most right and 16 to most left. Don't be confused by the appearently wrong
direction the slider moves the balance to right and left.< / p >
< table class = 'table table-striped' >
< tbody >
< tr >
< td > Balance (range -16 | +16)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_BALANCE_table_bottom' > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< / tbody >
< / table >
< br >
< hr >
< label for = 'balanceRange' class = 'form-label' > Balance (-16 to 16)< / label >
2024-03-26 18:18:03 +00:00
< input type = 'range' class = 'form-range' value = '16' min = '0' max = '32' id = 'updatedLabel_BALANCE_range_bottom'
onchange="http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/balance/' + this.value);http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 16:00:14 +00:00
<!-- EQUALIZER Collapsible -->
2024-03-26 11:23:59 +00:00
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse' data-bs-target = '#accordion-collapse-eq'
aria-expanded='true' aria-controls='accordion-collapse-eq'>
Equalizer
< span class = 'badge text-bg-info' > /api/v1/eq/< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-eq' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< table class = 'table table-striped' >
< tbody >
< tr >
< td > Equalizer Low (-40dB to 6dB)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_EQLOW_table_bottom' > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Equalizer Mid (-40dB to 6dB)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_EQMID_table_bottom' > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< tr >
< td > Equalizer High (-40dB to 6dB)< / td >
2024-03-26 17:02:24 +00:00
< td class = 'text-end' id = 'updatedLabel_EQHIGH_table_bottom' > < span class = "placeholder col-12" > < / span > < / td >
2024-03-26 11:23:59 +00:00
< / tr >
< / tbody >
< / table >
< br >
< hr >
< label for = 'eqLowRange' class = 'form-label' > Equalizer for lows (-40dB to 6dB)< / label >
2024-03-26 18:18:03 +00:00
< input type = 'range' class = 'form-range' value = '" + String(eqLow+40) + "' min = '0' max = '46' id = 'updatedLabel_EQLOW_range_bottom'
onchange="http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/eq/low/' + this.value);http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< br >
< hr >
< br > < label for = 'eqMidRange' class = 'form-label' > Equalizer for mids (-40dB to 6dB)< / label >
2024-03-26 18:18:03 +00:00
< input type = 'range' class = 'form-range' value = '" + String(eqMid+40) + "' min = '0' max = '46' id = 'updatedLabel_EQMID_range_bottom'
onchange="http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/eq/mid/' + this.value);http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< br >
< hr >
< br > < label for = 'eqHighRange' class = 'form-label' > Equalizer for highs (-40dB to 6dB)< / label >
2024-03-26 18:18:03 +00:00
< input type = 'range' class = 'form-range' value = '" + String(eqHigh+40) + "' min = '0' max = '46' id = 'updatedLabel_EQHIGH_range_bottom'
onchange="http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/eq/high/' + this.value);http.send();updateStrings();">
2024-03-26 11:23:59 +00:00
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 16:00:14 +00:00
<!-- FRIENDLY NAME Collapsible -->
2024-03-26 11:23:59 +00:00
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse'
data-bs-target='#accordion-collapse-frname' aria-expanded='true' aria-controls='accordion-collapse-frname'>
Friendly name
< span class = 'badge text-bg-warning' > /api/v1/system/name< / span >
<!-- explicitly no trailing / as there are the two endpoints /name and /name/change -->
< / button >
< / h2 >
< div id = 'accordion-collapse-frname' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< div class = 'input-group mb-3' >
2024-03-26 16:00:14 +00:00
< span class = 'input-group-text' id = 'updatedLabel_FRNAME_oldinputtext' > ...< / span >
2024-03-26 11:23:59 +00:00
< span class = 'input-group-text' > -> < / span >
< input type = 'text' class = 'form-control' placeholder = 'New friendly name' aria-label = 'New friendly name'
aria-describedby='frnameChange_BTN_submitName' id='frnameChange_newNameInput'>
2024-03-26 18:18:03 +00:00
< button class = 'btn btn-success' type = 'button' id = 'frnameChange_BTN_submitName' onclick = "
newName=document.getElementById('frnameChange_newNameInput').value;oldName=document.getElementById('updatedLabel_FRNAME_oldinputtext').innerHTML;
if(oldName != newName) {
http = new XMLHttpRequest();http.open('GET', 'http://' + document.cookie + '/api/v1/system/name/change?friendly_name=' + newName);http.send();
updateStrings();
}">
2024-03-26 17:02:24 +00:00
Change
< / button >
2024-03-26 11:23:59 +00:00
< / div >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
<!-- WiFi CONFIGURATION Collapsible -->
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse' data-bs-target = '#accordion-collapse-wifi'
aria-expanded='true' aria-controls='accordion-collapse-wifi'>
WiFi configuration
< span class = 'badge text-bg-warning' > /api/v1/system/wifi/< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-wifi' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< p > Demo for changing the wifi SSID and PSK (= Pre-Shared Key; well-known as 'Password' or 'Key'). There's no need to
give both - if you just wanna change the password - do it!< / p >
< p > After doing this, you have to go down to the restart collapsible. There, restart the NetSpeaker and it should connect
to the configured WiFi.< / p >
< p > If anything is wrong (either SSID or PSK wrong/typo, or the wifi's not available), the NetSpeaker opens an HotSpot
2024-03-26 18:33:09 +00:00
with the SSID < code id = "updatedLabel_APSSID_code" > ...< / code > and the PSK < code id = "updatedLabel_APPSK_code" > ...< / code > ! < / p >
2024-03-26 11:23:59 +00:00
< div class = 'input-group mb-3' >
< span class = 'input-group-text' > SSID< / span >
< input type = 'text' class = 'form-control' placeholder = 'Type in a new SSID here (optional)'
aria-label='Type in a new SSID here (optional)' aria-describedby='wifiChange_submitBtn'
id='wifiChange_ssidInput'>
< span class = 'input-group-text' > PSK< / span >
< input type = 'password' class = 'form-control' placeholder = 'Type in a new PSK here (optional)'
aria-label='Type in a new PSK here (optional)' aria-describedby='wifiChange_submitBtn'
id='wifiChange_pskInput'>
< button class = 'btn btn-success' type = 'button' id = 'wifiChange_submitBtn' onclick =
"newSSID
= document.getElementById('wifiChange_ssidInput').value;
newPSK = document.getElementById('wifiChange_pskInput').value;
http = new XMLHttpRequest();http.open('GET',
2024-03-26 18:33:09 +00:00
'http://' + document.cookie + '/api/v1/system/wifi/change?ssid='+newSSID+'&psk='+newPSK); http.send();">
2024-03-26 11:23:59 +00:00
Change
< / button >
< / div >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 16:00:14 +00:00
<!-- SAVE AND RESTORE Collapsible -->
2024-03-26 11:23:59 +00:00
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse'
data-bs-target='#accordion-collapse-restore' aria-expanded='true' aria-controls='accordion-collapse-restore'>
Save & Restore
< span class = 'badge text-bg-warning' > /api/v1/system/restore_state/< / span >
< span class = 'badge text-bg-warning' > /api/v1/system/restore_playing/< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-restore' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< p > Restoring the old/last state can be toggeled on or off over the API. Doing so can have many reasons, one could be
that you wanted to build a device always playing some startup sound, or so.< / p >
< div class = 'form-check form-switch' >
< input onclick = "this.value ? console.log('Toggeled on') : console.log('Toggeled off');" class = 'form-check-input'
type='checkbox' role='switch' id='restoreStateSwitch' " +
configuration.getBool(PREFERENCES_KEY_RESTORE_OLD_STATE,
true) ? "checked" : String() + " >
< label class = 'form-check-label' for = 'restoreStateSwitch' > Restore last saved state< / label >
< / div >
< div class = 'form-check form-switch' >
< input onclick = "this.value ? console.log('Toggeled on') : console.log('Toggeled off');" class = 'form-check-input'
type='checkbox' role='switch' id='restorePlayingSwitch' " +
configuration.getBool(PREFERENCES_KEY_RESTORE_PLAYING,
true) ? "checked" : String() + " >
< label class = 'form-check-label' for = 'restorePlayingSwitch' > Also restore last playing state< / label >
< / div >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 16:00:14 +00:00
<!-- RESTART Collapsible -->
2024-03-26 11:23:59 +00:00
< div class = 'accordion-item' >
< h2 class = 'accordion-header' >
< button class = 'accordion-button collapsed' type = 'button' data-bs-toggle = 'collapse'
data-bs-target='#accordion-collapse-restart' aria-expanded='true' aria-controls='accordion-collapse-restart'>
Restart
< span class = 'badge text-bg-danger' > /api/v1/system/restart< / span >
< / button >
< / h2 >
< div id = 'accordion-collapse-restart' class = 'accordion-collapse collapse' data-bs-parent = '#accordion' >
< div class = 'accordion-body' >
< button type = 'button' class = 'btn btn-danger' onclick = "function wait ( ms ) { var start = new Date ( ) . getTime ( ) ; var
end=start;while(end< start + ms ) { end
= new Date().getTime();}}http = new XMLHttpRequest();http.open('GET',
2024-03-26 18:33:09 +00:00
'http://' + document.cookie + '/api/v1/system/restart');http.send();wait(3000);window.location.reload();">
2024-03-26 11:23:59 +00:00
< svg xmlns = 'http://www.w3.org/2000/svg' width = '16' height = '16' fill = 'currentColor' class = 'bi bi-bootstrap-reboot'
viewBox='0 0 16 16'>
< path d = 'M1.161 8a6.84 6.84 0 1 0 6.842-6.84.58.58 0 1 1 0-1.16 8 8 0 1 1-6.556 3.412l-.663-.577a.58.58 0 0 1 .227-.997l2.52-.69a.58.58 0 0 1 .728.633l-.332 2.592a.58.58 0 0 1-.956.364l-.643-.56A6.812 6.812 0 0 0 1.16 8z' > < / path >
< path d = 'M6.641 11.671V8.843h1.57l1.498 2.828h1.314L9.377 8.665c.897-.3 1.427-1.106 1.427-2.1 0-1.37-.943-2.246-2.456-2.246H5.5v7.352zm0-3.75V5.277h1.57c.881 0 1.416.499 1.416 1.32 0 .84-.504 1.324-1.386 1.324h-1.6z' > < / path >
< / svg >
Restart
< / button >
< / div >
< / div >
< / div >
< / div >
2024-03-26 09:53:24 +00:00
2024-03-26 11:23:59 +00:00
<!-- Modal -->
< div class = "modal fade" id = "selectIPAddressModal" data-bs-backdrop = "static" data-bs-keyboard = "false" tabindex = "-1"
aria-labelledby="selectIPAddressModalLabel" aria-hidden="true">
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h1 class = "modal-title fs-5" id = "selectIPAddressModalLabel" > NetSpeaker configuration< / h1 >
< / div >
< div class = "text-start modal-body" >
< p > Please give the IP adress of you NetSpeaker here, so that this site can access its API.< / p >
2024-03-26 12:33:47 +00:00
< div class = "mb-3" >
2024-03-26 17:02:24 +00:00
< div class = "input-group" >
< span class = "input-group-text" > http://< / span >
< input type = "text" class = "form-control" id = "ipAdressInput" >
< / div >
2024-03-26 12:33:47 +00:00
< / div >
< div id = "configWorkingAlertPlaceholder" > < / div >
2024-03-26 11:23:59 +00:00
< / div >
< div class = "modal-footer" >
2024-03-26 12:33:47 +00:00
< button type = "button" class = "btn btn-primary" id = "ipAdressModalApplyBtn" > Apply & Test< / button >
< button type = "button" class = "btn btn-success" id = "ipAdressModalOkBtn" > Ok< / button >
2024-03-26 11:23:59 +00:00
< / div >
< / div >
< / div >
< / div >
< / div >
< script src = 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js'
integrity='sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL' crossorigin='anonymous'>< / script >
< script type = "text/javascript" >
2024-03-26 12:33:47 +00:00
function isValidIP(ipaddress) {
2024-03-26 11:23:59 +00:00
if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress)) {
return true;
}
return false;
}
2024-03-26 12:33:47 +00:00
function appendAlert(alertPlaceholder, message, type) {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`< div class = "alert alert-${type} alert-dismissible" role = "alert" > `,
` < div > ${message}< / div > `,
' < button type = "button" class = "btn-close" data-bs-dismiss = "alert" aria-label = "Close" > < / button > ',
'< / div > '
].join('')
alertPlaceholder.append(wrapper)
}
2024-03-26 16:00:14 +00:00
2024-03-26 17:02:24 +00:00
versionLabel1 = document.getElementById('updatedLabel_VERSION_title');
versionLabel2 = document.getElementById('updatedLabel_VERSION_table');
frnameLabel1 = document.getElementById('updatedLabel_FRNAME_title');
frnameLabel2 = document.getElementById('updatedLabel_FRNAME_table');
frnameLabel3 = document.getElementById('updatedLabel_FRNAME_oldinputtext');
restoreStateLabel1 = document.getElementById('updatedLabel_RESTORESTATE_table')
restorePlayingStateLabel1 = document.getElementById('updatedLabel_RESTOREPLAYING_table')
wifiLabel1 = document.getElementById('updatedLabel_WIFISSID_table');
2024-03-26 18:25:17 +00:00
apSsidLabel1 = document.getElementById('updatedLabel_APSSID_table');
2024-03-26 18:33:09 +00:00
apSsidLabel2 = document.getElementById('updatedLabel_APSSID_code');
2024-03-26 18:25:17 +00:00
apPskLabel1 = document.getElementById('updatedLabel_APPSK_table');
2024-03-26 18:33:09 +00:00
apPskLabel2 = document.getElementById('updatedLabel_APPSK_code');
2024-03-26 17:02:24 +00:00
const playingLabel1 = document.getElementById("updatedLabel_PLAYING_table_top");
const playingLabel2 = document.getElementById("updatedLabel_PLAYING_table_bottom");
const rs_plpathLabel1 = document.getElementById("updatedLabel_RS_PLPATH_table_top");
const rs_plidxLabel1 = document.getElementById("updatedLabel_RS_PLIDX_table_top");
const rs_pathLabel1 = document.getElementById("updatedLabel_RS_PATH_table_top");
const rs_typeLabel1 = document.getElementById("updatedLabel_RS_TYPE_table_top");
const rs_titleLabel1 = document.getElementById("updatedLabel_RS_TITLE_table_top");
const rs_albumLabel1 = document.getElementById("updatedLabel_RS_ALBUM_table_top");
const rs_artistLabel1 = document.getElementById("updatedLabel_RS_ARTIST_table_top");
const rs_tracknrLabel1 = document.getElementById("updatedLabel_RS_TRACKNR_table_top");
const rs_yearLabel1 = document.getElementById("updatedLabel_RS_YEAR_table_top");
const rs_genreLabel1 = document.getElementById("updatedLabel_RS_GENRE_table_top");
const rs_copyrightLabel1 = document.getElementById("updatedLabel_RS_COPYRIGHT_table_top");
const rs_languageLabel1 = document.getElementById("updatedLabel_RS_LANGUAGE_table_top");
volumeLabel1 = document.getElementById('updatedLabel_VOLUME_table_top');
volumeLabel2 = document.getElementById('updatedLabel_VOLUME_table_bottom');
2024-03-26 18:18:03 +00:00
volumeRange1 = document.getElementById('updatedLabel_VOLUME_range_bottom');
2024-03-26 17:02:24 +00:00
mutedLabel1 = document.getElementById('updatedLabel_MUTED_table_top');
mutedLabel2 = document.getElementById('updatedLabel_MUTED_table_bottom');
eqLowLabel1 = document.getElementById('updatedLabel_EQLOW_table_top');
eqLowLabel2 = document.getElementById('updatedLabel_EQLOW_table_bottom');
2024-03-26 18:18:03 +00:00
eqLowRange1 = document.getElementById('updatedLabel_EQLOW_range_bottom');
2024-03-26 17:02:24 +00:00
eqMidLabel1 = document.getElementById('updatedLabel_EQMID_table_top');
eqMidLabel2 = document.getElementById('updatedLabel_EQMID_table_bottom');
2024-03-26 18:18:03 +00:00
eqMidRange1 = document.getElementById('updatedLabel_EQMID_range_bottom');
2024-03-26 17:02:24 +00:00
eqHighLabel1 = document.getElementById('updatedLabel_EQHIGH_table_top');
eqHighLabel2 = document.getElementById('updatedLabel_EQHIGH_table_bottom');
2024-03-26 18:18:03 +00:00
eqHighRange1 = document.getElementById('updatedLabel_EQHIGH_range_bottom');
2024-03-26 17:02:24 +00:00
balanceLabel1 = document.getElementById('updatedLabel_BALANCE_table_top');
balanceLabel2 = document.getElementById('updatedLabel_BALANCE_table_bottom');
2024-03-26 18:18:03 +00:00
balanceRange1 = document.getElementById('updatedLabel_BALANCE_range_bottom');
2024-03-26 17:02:24 +00:00
2024-03-26 16:00:14 +00:00
function updateStrings() {
2024-03-26 17:02:24 +00:00
apiBase = "http://" + document.cookie;
versionApiEndpoint = "/api/v1/system/version";
frnameApiEndpoint = "/api/v1/system/name";
restoreStateApiEndpoint = "/api/v1/system/restore_state/get";
2024-03-26 16:00:14 +00:00
restorePlayingStateApiEndpoint = "/api/v1/system/restore_playing/get";
2024-03-26 17:02:24 +00:00
wifiApiEndpoint = "/api/v1/system/wifi/get_ssid";
2024-03-26 18:25:17 +00:00
apApiEndpoint = "/api/v1/system/wifi/get_ap_creds";
2024-03-26 17:02:24 +00:00
playbackInfoApiEndpoint = "/api/v1/playback/info";
volumeApiEndpoint = "/api/v1/volume/get";
eqApiEndpoint = "/api/v1/eq/get";
balanceApiEndpoint = "/api/v1/balance/get";
2024-03-26 16:00:14 +00:00
/* Version string parser */
var versionRequest = new XMLHttpRequest();
versionRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var versionString = JSON.parse(this.responseText).version;
versionLabel1.innerHTML = versionString;
versionLabel2.innerHTML = versionString;
}
}
versionRequest.open("GET", apiBase + versionApiEndpoint, true);
versionRequest.send();
/* friendly name parser */
var frnameRequest = new XMLHttpRequest();
frnameRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var frnameString = JSON.parse(this.responseText).friendly_name;
frnameLabel1.innerHTML = frnameString;
frnameLabel2.innerHTML = frnameString;
frnameLabel3.innerHTML = frnameString;
}
}
frnameRequest.open("GET", apiBase + frnameApiEndpoint, true);
frnameRequest.send();
/* Save & Restore parser */
var restoreStateRequest = new XMLHttpRequest();
restoreStateRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var restoreStateString = JSON.parse(this.responseText).restore_state;
restoreStateLabel1.innerHTML = restoreStateString ? "yes" : "no";
}
}
restoreStateRequest.open("GET", apiBase + restoreStateApiEndpoint, true);
restoreStateRequest.send();
var restorePlayingRequest = new XMLHttpRequest();
restorePlayingRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var restorePlayingString = JSON.parse(this.responseText).restore_playing;
restorePlayingStateLabel1.innerHTML = restorePlayingString ? "yes" : "no";
}
}
restorePlayingRequest.open("GET", apiBase + restorePlayingStateApiEndpoint, true);
restorePlayingRequest.send();
/* WiFi SSID parser */
var wifiRequest = new XMLHttpRequest();
wifiRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var wifiSsidString = JSON.parse(this.responseText).wifi_ssid;
wifiLabel1.innerHTML = wifiSsidString;
}
}
wifiRequest.open("GET", apiBase + wifiApiEndpoint, true);
wifiRequest.send();
2024-03-26 18:25:17 +00:00
/* AP SSID and PSK parser */
var apRequest = new XMLHttpRequest();
apRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var apSsidString = JSON.parse(this.responseText).ap_ssid;
var apPskString = JSON.parse(this.responseText).ap_psk;
apSsidLabel1.innerHTML = apSsidString;
2024-03-26 18:33:09 +00:00
apSsidLabel2.innerHTML = apSsidString;
2024-03-26 18:25:17 +00:00
apPskLabel1.innerHTML = apPskString;
2024-03-26 18:33:09 +00:00
apPskLabel2.innerHTML = apPskString;
2024-03-26 18:25:17 +00:00
}
}
apRequest.open("GET", apiBase + apApiEndpoint, true);
apRequest.send();
2024-03-26 16:00:14 +00:00
/* Playback info parser */
2024-03-26 17:02:24 +00:00
var playbackInfoRequest = new XMLHttpRequest();
playbackInfoRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var playbackInfoResponse = JSON.parse(this.responseText);
playingLabel1.innerHTML = playbackInfoResponse.state == "playing" ? "yes" : "no";
playingLabel2.innerHTML = playbackInfoResponse.state == "playing" ? "yes" : "no";
rs_plpathLabel1.innerHTML = playbackInfoResponse.resource_playlist_path;
rs_plidxLabel1.innerHTML = playbackInfoResponse.resource_playlist_index;
rs_pathLabel1.innerHTML = playbackInfoResponse.resource_path;
rs_typeLabel1.innerHTML = playbackInfoResponse.resource_type;
rs_titleLabel1.innerHTML = playbackInfoResponse.resource_title;
rs_albumLabel1.innerHTML = playbackInfoResponse.resource_album;
rs_artistLabel1.innerHTML = playbackInfoResponse.resource_artist;
rs_tracknrLabel1.innerHTML = playbackInfoResponse.resource_track;
rs_yearLabel1.innerHTML = playbackInfoResponse.resource_year;
rs_genreLabel1.innerHTML = playbackInfoResponse.resource_genre;
rs_copyrightLabel1.innerHTML = playbackInfoResponse.resource_copyright;
rs_languageLabel1.innerHTML = playbackInfoResponse.resource_tts_language;
}
}
playbackInfoRequest.open("GET", apiBase + playbackInfoApiEndpoint, true);
playbackInfoRequest.send();
/* Volume+Muted parser */
var volumeRequest = new XMLHttpRequest();
volumeRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var volumeValue = JSON.parse(this.responseText).volume;
var maxVolumeValue = JSON.parse(this.responseText).volume_max;
var mutedValue = JSON.parse(this.responseText).muted;
volumeLabel1.innerHTML = volumeValue + "/" + maxVolumeValue;
volumeLabel2.innerHTML = volumeValue + "/" + maxVolumeValue;
mutedLabel1.innerHTML = mutedValue ? "yes" : "no";
mutedLabel2.innerHTML = mutedValue ? "yes" : "no";
2024-03-26 18:18:03 +00:00
volumeRange1.max = maxVolumeValue;
volumeRange1.value = volumeValue;
2024-03-26 17:02:24 +00:00
}
}
volumeRequest.open("GET", apiBase + volumeApiEndpoint, true);
volumeRequest.send();
2024-03-26 16:00:14 +00:00
/* Equalizer parser */
2024-03-26 17:02:24 +00:00
var eqRequest = new XMLHttpRequest();
eqRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var eqLowValue = JSON.parse(this.responseText).equalizer_low;
var eqMidValue = JSON.parse(this.responseText).equalizer_mid;
var eqHighValue = JSON.parse(this.responseText).equalizer_high;
2024-03-26 18:18:03 +00:00
eqLowLabel1.innerHTML = eqLowValue + "dB";
eqLowLabel2.innerHTML = eqLowValue + "dB";
eqLowRange1.value = eqLowValue + 40;
eqMidLabel1.innerHTML = eqMidValue + "dB";
eqMidLabel2.innerHTML = eqMidValue + "dB";
eqMidRange1.value = eqMidValue + 40;
eqHighLabel1.innerHTML = eqHighValue + "dB";
eqHighLabel2.innerHTML = eqHighValue + "dB";
eqHighRange1.value = eqHighValue + 40;
2024-03-26 17:02:24 +00:00
}
}
eqRequest.open("GET", apiBase + eqApiEndpoint, true);
eqRequest.send();
2024-03-26 16:00:14 +00:00
/* Balance parser */
2024-03-26 17:02:24 +00:00
var balanceRequest = new XMLHttpRequest();
balanceRequest.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
var balanceValue = JSON.parse(this.responseText).balance;
balanceLabel1.innerHTML = balanceValue;
balanceLabel2.innerHTML = balanceValue;
2024-03-26 18:18:03 +00:00
balanceRange1.value = balanceValue + 16; // as the slider goes from 0 to 32 (as the API accepts it)
2024-03-26 17:02:24 +00:00
}
}
balanceRequest.open("GET", apiBase + balanceApiEndpoint, true);
balanceRequest.send();
2024-03-26 16:00:14 +00:00
}
function setupSite() {
document.title = "NetSpeaker Demo (on " + document.cookie + ")";
document.getElementById("title_onIP").innerHTML = "on " + document.cookie;
setTimeout(updateStrings, 1000); // to make user see the epic placeholder glow effect of the bootstrap library
2024-03-26 17:03:02 +00:00
setInterval(updateStrings, 10000);
2024-03-26 16:00:14 +00:00
}
2024-03-26 18:18:03 +00:00
window.onload = function(e) {
if (document.cookie == "" || !isValidIP(document.cookie)) {
var selectIPModal = new bootstrap.Modal(document.getElementById('selectIPAddressModal'), {});
selectIPModal.show();
const alertPlaceholder = document.getElementById('configWorkingAlertPlaceholder');
function configButtonEventListener(hideModalOnSuccess) {
var ipAddressEntered = document.getElementById('ipAdressInput').value;
if(isValidIP(ipAddressEntered)) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 & & this.status == 200) {
appendAlert(alertPlaceholder, 'Working Configuration!', 'success');
document.cookie = ipAddressEntered;
setupSite()
setTimeout(function(){
if(hideModalOnSuccess) selectIPModal.hide();
}, 500);
} else if (this.readyState != 4) {
// just do nothing, wait!
} else {
appendAlert(alertPlaceholder, 'Configuration not working', 'danger');
}
};
request.open("GET", "http://" + ipAddressEntered + "/api/v1/system/version", true);
request.send()
} else {
appendAlert(alertPlaceholder, 'Configuration not working', 'danger');
}
2024-03-26 12:33:47 +00:00
}
2024-03-26 18:18:03 +00:00
const ipAdressModalApplyBtn = document.getElementById('ipAdressModalApplyBtn');
ipAdressModalApplyBtn.addEventListener('click', () => { configButtonEventListener(false); });
2024-03-26 12:33:47 +00:00
2024-03-26 18:18:03 +00:00
const ipAdressModalOkBtn = document.getElementById('ipAdressModalOkBtn');
ipAdressModalOkBtn.addEventListener('click', () => { configButtonEventListener(true); });
2024-03-26 16:00:14 +00:00
2024-03-26 18:18:03 +00:00
} else if (isValidIP(document.cookie)) setupSite();
} // end of onload function
2024-03-26 11:23:59 +00:00
< / script >
< / body >
2024-03-26 17:02:24 +00:00
< / html >
<!-- An uncomplete list of XML IDs used in this piece of HTML:
updatedLabel_PLAYING_table_top
updatedLabel_PLAYING_table_bottom
updatedLabel_VOLUME_table_top
updatedLabel_VOLUME_table_bottom
updatedLabel_MUTED_table_top
updatedLabel_MUTED_table_bottom
updatedLabel_BALANCE_table_top
updatedLabel_BALANCE_table_bottom
updatedLabel_EQLOW_table_top
updatedLabel_EQLOW_table_bottom
updatedLabel_EQMID_table_top
updatedLabel_EQMID_table_bottom
updatedLabel_EQHIGH_table_top
updatedLabel_EQHIGH_table_bottom
updatedLabel_RS_PLPATH_table_top
updatedLabel_RS_PLIDX_table_top
updatedLabel_RS_PATH_table_top
updatedLabel_RS_TYPE_table_top
updatedLabel_RS_TITLE_table_top
updatedLabel_RS_ALBUM_table_top
updatedLabel_RS_ARTIST_table_top
updatedLabel_RS_TRACKNR_table_top
updatedLabel_RS_YEAR_table_top
updatedLabel_RS_GENRE_table_top
updatedLabel_RS_COPYRIGHT_table_top
updatedLabel_RS_LANGUAGE_table_top
-->