1
0
mirror of https://github.com/SuperBFG7/ympd synced 2025-07-28 22:22:49 +00:00

Feat: startup screen, connect to websocket after getting the settings

This commit is contained in:
jcorporation 2019-01-14 23:06:07 +00:00
parent 230395e445
commit 2f3a579d07
4 changed files with 100 additions and 19 deletions

View File

@ -91,6 +91,10 @@ small {
display: none !important; display: none !important;
} }
.unvisible {
visibility: hidden;
}
.pull-right { .pull-right {
float: right !important; float: right !important;
} }

View File

@ -16,7 +16,7 @@
<link rel="apple-touch-icon" href="/assets/appicon-167.png"> <link rel="apple-touch-icon" href="/assets/appicon-167.png">
</head> </head>
<body> <body>
<header> <header class="hide">
<nav class="navbar navbar-expand navbar-dark fixed-top bg-dark"> <nav class="navbar navbar-expand navbar-dark fixed-top bg-dark">
<div class="dropdown col-auto mr-auto pl-0"> <div class="dropdown col-auto mr-auto pl-0">
<a class="dropdown-toggle navbar-brand" href="#" id="mainMenu"> <a class="dropdown-toggle navbar-brand" href="#" id="mainMenu">
@ -74,7 +74,7 @@
</div> </div>
</nav> </nav>
</header> </header>
<main class="container"> <main class="container hide">
<noscript> <noscript>
<div class="alert alert-danger">JavaScript is disabled!</div> <div class="alert alert-danger">JavaScript is disabled!</div>
</noscript> </noscript>
@ -607,7 +607,7 @@
</div> </div>
</main> </main>
<footer class="footer"> <footer class="footer hide">
<nav class="navbar navbar-expand navbar-dark fixed-bottom bg-dark"> <nav class="navbar navbar-expand navbar-dark fixed-bottom bg-dark">
<div class="d-flex flex-fill navbar-nav" id="navbar-bottom"> <div class="d-flex flex-fill navbar-nav" id="navbar-bottom">
<div id="navPlayback" class="nav-item flex-fill text-center"><a data-href='{"cmd": "appGoto", "options": ["Playback"]}' class="nav-link" href="#">Playback</a></div> <div id="navPlayback" class="nav-item flex-fill text-center"><a data-href='{"cmd": "appGoto", "options": ["Playback"]}' class="nav-link" href="#">Playback</a></div>
@ -619,6 +619,23 @@
</footer> </footer>
<!-- Modals --> <!-- Modals -->
<div class="modal fade" id="modalAppInit" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-success text-light">
<h5 class="modal-title"><span class="material-icons title-icon">play_circle_outline</span> Initializing myMPD</h5>
</div>
<div class="modal-body">
<p>Please wait, myMPD is initializing...</p>
<p><span id="appInitSettings" class="material-icons unvisible">check</span> Fetch settings</p>
<p><span id="appInitWebsocket" class="material-icons unvisible">check</span> Connect to websocket</p>
<p><span id="appInitApply" class="material-icons unvisible">check</span> Applying settings</p>
</div>
</div>
</div>
</div>
<div class="modal fade" id="modalConnectionError" tabindex="-1"> <div class="modal fade" id="modalConnectionError" tabindex="-1">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">

View File

@ -29,12 +29,16 @@ var lastSongObj = {};
var lastState; var lastState;
var currentSong = new Object(); var currentSong = new Object();
var playstate = ''; var playstate = '';
var settingsLock = false;
var settingsParsed = false;
var settingsNew = {};
var settings = {}; var settings = {};
var alertTimeout; var alertTimeout;
var progressTimer; var progressTimer;
var deferredPrompt; var deferredPrompt;
var dragEl; var dragEl;
var playlistEl; var playlistEl;
var websocketConnected = false;
var app = {}; var app = {};
app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 },
@ -104,6 +108,7 @@ var modalUpdateDB = new Modal(document.getElementById('modalUpdateDB'));
var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPlaylist')); var modalSaveSmartPlaylist = new Modal(document.getElementById('modalSaveSmartPlaylist'));
var modalDeletePlaylist = new Modal(document.getElementById('modalDeletePlaylist')); var modalDeletePlaylist = new Modal(document.getElementById('modalDeletePlaylist'));
var modalHelp = new Modal(document.getElementById('modalHelp')); var modalHelp = new Modal(document.getElementById('modalHelp'));
var modalAppInit = new Modal(document.getElementById('modalAppInit'));
var dropdownMainMenu; var dropdownMainMenu;
var dropdownVolumeMenu = new Dropdown(document.getElementById('volumeMenu')); var dropdownVolumeMenu = new Dropdown(document.getElementById('volumeMenu'));
@ -353,10 +358,37 @@ function appRoute() {
app.last.view = app.current.view; app.last.view = app.current.view;
}; };
function appInit() { function appInitStart() {
webSocketConnect(); modalAppInit.show();
getSettings(); getSettings();
sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState); appInitWait();
}
function appInitWait() {
setTimeout(function() {
if (settingsParsed == true && websocketConnected == true) {
//app initialized
document.getElementById('appInitWebsocket').classList.remove('unvisible');
appInit();
document.getElementById('appInitApply').classList.remove('unvisible');
document.getElementsByTagName('header')[0].classList.remove('hide');
document.getElementsByTagName('main')[0].classList.remove('hide');
document.getElementsByTagName('footer')[0].classList.remove('hide');
modalAppInit.hide();
return;
}
if (settingsParsed == true) {
//parsed settings, now its save to connect to websocket
document.getElementById('appInitSettings').classList.remove('unvisible');
webSocketConnect();
}
appInitWait();
}, 500);
}
function appInit() {
//sendAPI({"cmd": "MPD_API_PLAYER_STATE"}, parseState);
domCache.volumeBar.value = 0; domCache.volumeBar.value = 0;
@ -811,6 +843,12 @@ function appInit() {
window.addEventListener('appinstalled', function(event) { window.addEventListener('appinstalled', function(event) {
console.log('myMPD installed as app'); console.log('myMPD installed as app');
}); });
window.addEventListener('beforeunload', function() {
socket.onclose = function () {}; // disable onclose handler first
socket.close();
websocketConnected = false;
});
} }
function parseCmd(event, href) { function parseCmd(event, href) {
@ -1028,6 +1066,9 @@ function webSocketConnect() {
} }
switch (obj.type) { switch (obj.type) {
case 'welcome':
websocketConnected = true;
break;
case 'update_state': case 'update_state':
parseState(obj); parseState(obj);
break; break;
@ -1070,6 +1111,7 @@ function webSocketConnect() {
} }
socket.onclose = function(){ socket.onclose = function(){
websocketConnected = false;
console.log('disconnected'); console.log('disconnected');
modalConnectionError.show(); modalConnectionError.show();
setTimeout(function() { setTimeout(function() {
@ -1145,8 +1187,8 @@ function filterCols(x) {
settings[x] = cols; settings[x] = cols;
} }
function parseSettings(obj) { function parseSettings() {
settings = obj.data; settingsParsed = false;
toggleBtn('btnRandom', settings.random); toggleBtn('btnRandom', settings.random);
toggleBtn('btnConsume', settings.consume); toggleBtn('btnConsume', settings.consume);
@ -1300,12 +1342,12 @@ function parseSettings(obj) {
if (settings.featSyscmds) { if (settings.featSyscmds) {
var mainMenuDropdown = document.getElementById('mainMenuDropdown'); var mainMenuDropdown = document.getElementById('mainMenuDropdown');
var syscmdsList = ''; var syscmdsList = '';
var syscmdsListLen = settings.syscmds.length; var syscmdsListLen = settings.syscmdList.length;
if (syscmdsListLen > 0) { if (syscmdsListLen > 0) {
syscmdsList = '<div class="dropdown-divider"></div>'; syscmdsList = '<div class="dropdown-divider"></div>';
for (var i = 0; i < syscmdsListLen; i++) { for (var i = 0; i < syscmdsListLen; i++) {
syscmdsList += '<a class="dropdown-item text-light bg-dark" href="#" data-href=\'{"cmd": "execSyscmd", "options": ["' + syscmdsList += '<a class="dropdown-item text-light bg-dark" href="#" data-href=\'{"cmd": "execSyscmd", "options": ["' +
settings.syscmds[i] + '"]}\'>' + settings.syscmds[i] + '</a>'; settings.syscmdList[i] + '"]}\'>' + settings.syscmdList[i] + '</a>';
} }
} }
document.getElementById('syscmds').innerHTML = syscmdsList; document.getElementById('syscmds').innerHTML = syscmdsList;
@ -1333,6 +1375,8 @@ function parseSettings(obj) {
appRoute(); appRoute();
else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.search != '') else if (app.current.app == 'Browse' && app.current.tab == 'Database' && app.current.search != '')
appRoute(); appRoute();
settingsParsed = true;
} }
function setCols(table, className) { function setCols(table, className) {
@ -1404,7 +1448,24 @@ function setCols(table, className) {
} }
function getSettings() { function getSettings() {
sendAPI({"cmd": "MPD_API_SETTINGS_GET"}, parseSettings); if (settingsLock == false) {
settingsLock = true;
sendAPI({"cmd": "MYMPD_API_SETTINGS_GET"}, getMpdSettings);
}
}
function getMpdSettings(obj) {
settingsNew = obj.data;
sendAPI({"cmd": "MPD_API_SETTINGS_GET"}, joinSettings);
}
function joinSettings(obj) {
for (var key in obj.data) {
settingsNew[key] = obj.data[key];
}
settings = Object.assign({}, settingsNew);
settingsLock = false;
parseSettings();
} }
function saveCols(table, tableEl) { function saveCols(table, tableEl) {
@ -1431,7 +1492,7 @@ function saveCols(table, tableEl) {
} }
} }
var cols = {"cmd": "MPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}}; var cols = {"cmd": "MYMPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}};
var ths = header.getElementsByTagName('th'); var ths = header.getElementsByTagName('th');
for (var i = 0; i < ths.length; i++) { for (var i = 0; i < ths.length; i++) {
var name = ths[i].getAttribute('data-col'); var name = ths[i].getAttribute('data-col');
@ -1460,7 +1521,7 @@ function saveColsPlayback(table) {
} }
} }
var cols = {"cmd": "MPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}}; var cols = {"cmd": "MYMPD_API_COLS_SAVE", "data": {"table": "cols" + table, "cols": []}};
var ths = header.getElementsByTagName('div'); var ths = header.getElementsByTagName('div');
for (var i = 0; i < ths.length; i++) { for (var i = 0; i < ths.length; i++) {
var name = ths[i].getAttribute('data-tag'); var name = ths[i].getAttribute('data-tag');
@ -2865,7 +2926,7 @@ function confirmSettings() {
var selectReplaygain = document.getElementById('selectReplaygain'); var selectReplaygain = document.getElementById('selectReplaygain');
var selectJukeboxPlaylist = document.getElementById('selectJukeboxPlaylist'); var selectJukeboxPlaylist = document.getElementById('selectJukeboxPlaylist');
var selectJukeboxMode = document.getElementById('selectJukeboxMode'); var selectJukeboxMode = document.getElementById('selectJukeboxMode');
sendAPI({"cmd": "MPD_API_SETTINGS_SET", "data": { sendAPI({"cmd": "MYMPD_API_SETTINGS_SET", "data": {
"consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0), "consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0),
"random": (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0), "random": (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0),
"single": (document.getElementById('btnSingle').classList.contains('active') ? 1 : 0), "single": (document.getElementById('btnSingle').classList.contains('active') ? 1 : 0),
@ -3162,4 +3223,4 @@ function genId(x) {
} }
//Init app //Init app
appInit(); appInitStart();

View File

@ -211,6 +211,7 @@ static void mympd_api(t_config *config, t_mympd_state *mympd_state, t_work_reque
//push settings to mpd_client queue //push settings to mpd_client queue
t_work_request *mpd_client_request = (t_work_request *)malloc(sizeof(t_work_request)); t_work_request *mpd_client_request = (t_work_request *)malloc(sizeof(t_work_request));
mpd_client_request->conn_id = request->conn_id; mpd_client_request->conn_id = request->conn_id;
mpd_client_request->cmd_id = request->cmd_id;
mpd_client_request->length = copy_string(mpd_client_request->data, request->data, MAX_SIZE, request->length); mpd_client_request->length = copy_string(mpd_client_request->data, request->data, MAX_SIZE, request->length);
tiny_queue_push(mpd_client_queue, mpd_client_request); tiny_queue_push(mpd_client_queue, mpd_client_request);
} }
@ -411,15 +412,13 @@ static int mympd_api_put_settings(t_config *config, t_mympd_state *mympd_state,
int nr = 0; int nr = 0;
struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE);
len = json_printf(&out, "{type: settings, data: {mpdhost: %Q, mpdport: %d, passwort_set: %B, featSyscmds: %B, featStickers: %B, featSmartpls: %B, " len = json_printf(&out, "{type: mympdSettings, data: {mpdhost: %Q, mpdport: %d, passwort_set: %B, featSyscmds: %B, "
"featLocalplayer: %B, streamport: %d, streamurl: %Q, featCoverimage: %B, coverimagename: %Q, coverimagesize: %d, featMixramp: %B, " "featLocalplayer: %B, streamport: %d, streamurl: %Q, featCoverimage: %B, coverimagename: %Q, coverimagesize: %d, featMixramp: %B, "
"maxElementsPerPage: %d, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d", "maxElementsPerPage: %d, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d",
config->mpdhost, config->mpdhost,
config->mpdport, config->mpdport,
config->mpdpass ? "true" : "false", config->mpdpass ? "true" : "false",
config->syscmds, config->syscmds,
config->stickers,
config->smartpls,
config->localplayer, config->localplayer,
config->streamport, config->streamport,
config->streamurl, config->streamurl,
@ -436,7 +435,7 @@ static int mympd_api_put_settings(t_config *config, t_mympd_state *mympd_state,
); );
if (config->syscmds == true) { if (config->syscmds == true) {
len += json_printf(&out, ", syscmds: ["); len += json_printf(&out, ", syscmdList: [");
nr = 0; nr = 0;
struct node *current = mympd_state->syscmd_list.list; struct node *current = mympd_state->syscmd_list.list;
while (current != NULL) { while (current != NULL) {