diff --git a/htdocs/js/mympd.js b/htdocs/js/mympd.js index 075cfbc..9b6c16f 100644 --- a/htdocs/js/mympd.js +++ b/htdocs/js/mympd.js @@ -39,22 +39,23 @@ var deferredPrompt; var dragEl; var playlistEl; var websocketConnected = false; +var appInited = false; var app = {}; -app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, +app.apps = { "Playback": { "state": "0/-/-/", "scrollPos": 0 }, "Queue": { "active": "Current", - "tabs": { "Current": { "state": "0/any/", "scrollPos": 0 }, - "LastPlayed": { "state": "0/any/", "scrollPos": 0 } + "tabs": { "Current": { "state": "0/any/-/", "scrollPos": 0 }, + "LastPlayed": { "state": "0/any/-/", "scrollPos": 0 } } }, "Browse": { "active": "Database", - "tabs": { "Filesystem": { "state": "0/-/", "scrollPos": 0 }, + "tabs": { "Filesystem": { "state": "0/-/-/", "scrollPos": 0 }, "Playlists": { "active": "All", - "views": { "All": { "state": "0/-/", "scrollPos": 0 }, - "Detail": { "state": "0/-/", "scrollPos": 0 } + "views": { "All": { "state": "0/-/-/", "scrollPos": 0 }, + "Detail": { "state": "0/-/-/", "scrollPos": 0 } } }, "Database": { @@ -64,11 +65,11 @@ app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, } } }, - "Search": { "state": "0/any/", "scrollPos": 0 } + "Search": { "state": "0/any/-/", "scrollPos": 0 } }; -app.current = { "app": "Playback", "tab": undefined, "view": undefined, "page": 0, "filter": "", "search": "", "scrollPos": 0 }; -app.last = { "app": undefined, "tab": undefined, "view": undefined, "filter": "", "search": "", "scrollPos": 0 }; +app.current = { "app": "Playback", "tab": undefined, "view": undefined, "page": 0, "filter": "", "search": "", "sort": "", "scrollPos": 0 }; +app.last = { "app": undefined, "tab": undefined, "view": undefined, "filter": "", "search": "", "sort": "", "scrollPos": 0 }; var domCache = {}; domCache.navbarBottomBtns = document.getElementById('navbar-bottom').getElementsByTagName('div'); @@ -189,7 +190,7 @@ function appRoute() { } var hash = decodeURI(location.hash); var params; - if (params = hash.match(/^\#\/(\w+)\/?(\w+)?\/?(\w+)?\!((\d+)\/([^\/]+)\/(.*))$/)) { + if (params = hash.match(/^\#\/(\w+)\/?(\w+)?\/?(\w+)?\!((\d+)\/([^\/]+)\/([^\/]+)\/(.*))$/)) { app.current.app = params[1]; app.current.tab = params[2]; app.current.view = params[3]; @@ -210,7 +211,8 @@ function appRoute() { } app.current.page = parseInt(params[5]); app.current.filter = params[6]; - app.current.search = params[7]; + app.current.sort = params[7]; + app.current.search = params[8]; } else { appGoto('Playback'); @@ -322,13 +324,13 @@ function appRoute() { if (domCache.searchstr.value.length >= 2 || domCache.searchCrumb.children.length > 0) { if (settings.featAdvsearch) { - var sort = document.getElementById('SearchList').getAttribute('data-sort'); + var sort = app.current.sort;//document.getElementById('SearchList').getAttribute('data-sort'); var sortdesc = false; - if (sort == '') { + if (sort == '-') { if (settings.tags.includes('Title')) sort = 'Title'; else - sort = ''; + sort = '-'; document.getElementById('SearchList').setAttribute('data-sort', sort); } else { @@ -363,6 +365,7 @@ function appRoute() { }; function appInitStart() { + appInited = false; document.getElementsByTagName('header')[0].classList.add('hide'); document.getElementsByTagName('main')[0].classList.add('hide'); document.getElementsByTagName('footer')[0].classList.add('hide'); @@ -385,6 +388,7 @@ function appInitWait() { document.getElementsByTagName('main')[0].classList.remove('hide'); document.getElementsByTagName('footer')[0].classList.remove('hide'); modalAppInit.hide(); + appInited = true; return; } @@ -742,7 +746,7 @@ function appInit() { var col = event.target.getAttribute('data-col'); if (col == 'Duration') return; - var sortcol = document.getElementById('SearchList').getAttribute('data-sort'); + var sortcol = app.current.sort; //document.getElementById('SearchList').getAttribute('data-sort'); var sortdesc = true; if (sortcol == col || sortcol == '-' + col) { @@ -765,9 +769,11 @@ function appInit() { var s = document.getElementById('SearchList').getElementsByClassName('sort-dir'); for (var i = 0; i < s.length; i++) s[i].remove(); - document.getElementById('SearchList').setAttribute('data-sort', sortcol); + //document.getElementById('SearchList').setAttribute('data-sort', sortcol); + app.current.sort = sortcol; event.target.innerHTML = col + '' + (sortdesc == true ? 'arrow_drop_up' : 'arrow_drop_down') + ''; - appRoute(); + appGoto(app.current.app, app.current.tab, app.current.view, app.current.page + '/' + app.current.filter + '/' + app.current.sort + '/' + app.current.search); + //appRoute(); } } }, false); @@ -894,10 +900,10 @@ function search(x) { expression += ')'; if (expression.length <= 2) expression = ''; - appGoto('Search', undefined, undefined, '0/' + app.current.filter + '/' + encodeURI(expression)); + appGoto('Search', undefined, undefined, '0/' + app.current.filter + '/' + app.current.sort + '/' + encodeURI(expression)); } else - appGoto('Search', undefined, undefined, '0/' + app.current.filter + '/' + x); + appGoto('Search', undefined, undefined, '0/' + app.current.filter + '/' + app.current.sort + '/' + x); } function dragAndDropTable(table) { @@ -1122,7 +1128,7 @@ function webSocketConnect() { socket.onclose = function(){ console.log('Websocket is disconnected'); - if (websocketConnected == true) { + if (appInited == true) { //Show modal only if websocket was already connected before modalConnectionError.show(); } @@ -1302,6 +1308,9 @@ function parseSettings() { else app.apps.Browse.tabs.Database.active = settings.tags[0]; } + if (settings.tags.includes('Title')) { + app.apps.Search.sort = 'Title'; + } document.getElementById('selectJukeboxMode').value = settings.jukeboxMode; document.getElementById('inputJukeboxQueueLength').value = settings.jukeboxQueueLength; @@ -1350,7 +1359,7 @@ function parseSettings() { addTagList('searchtags', 'searchtags'); for (var i = 0; i < settings.tags.length; i++) - app.apps.Browse.tabs.Database.views[settings.tags[i]] = { "state": "0/-/", "scrollPos": 0 }; + app.apps.Browse.tabs.Database.views[settings.tags[i]] = { "state": "0/-/-/", "scrollPos": 0 }; if (settings.featSyscmds) { var mainMenuDropdown = document.getElementById('mainMenuDropdown'); @@ -1420,12 +1429,12 @@ function setCols(table, className) { } document.getElementById(table + 'ColsDropdown').firstChild.innerHTML = tagChks; - var sort = document.getElementById('SearchList').getAttribute('data-sort'); - if (sort == '') { + //var sort = document.getElementById('SearchList').getAttribute('data-sort'); + if (app.current.sort == '-') { if (settings.featTags) - sort = 'Title'; + app.current.sort = 'Title'; else - sort = 'Filename'; + app.current.sort = 'Filename'; } if (table != 'Playback') { @@ -1439,9 +1448,9 @@ function setCols(table, className) { if (table == 'Search' && h == sort ) { var sortdesc = false; - if (sort.indexOf('-') == 0) { + if (app.current.sort.indexOf('-') == 0) { sortdesc = true; - sort = sort.substring(1); + //sort = sort.substring(1); } heading += '' + (sortdesc == true ? 'arrow_drop_up' : 'arrow_drop_down') + ''; } @@ -2256,7 +2265,7 @@ function gotoBrowse(x) { var tag = x.parentNode.getAttribute('data-tag'); var name = decodeURI(x.parentNode.getAttribute('data-name')); if (tag != '' && name != '' && name != '-' && settings.browsetags.includes(tag)) - appGoto('Browse', 'Database', tag, '0/-/' + name); + appGoto('Browse', 'Database', tag, '0/-/-/' + name); } function songDetails(uri) { @@ -2311,7 +2320,7 @@ function execSyscmd(cmd) { function playlistDetails(uri) { document.getElementById('BrowsePlaylistsAllList').classList.add('opacity05'); - appGoto('Browse', 'Playlists', 'Detail', '0/-/' + uri); + appGoto('Browse', 'Playlists', 'Detail', '0/-/-/' + uri); } function removeFromPlaylist(uri, pos) { @@ -3000,7 +3009,7 @@ function gotoPage(x) { default: app.current.page = x; } - appGoto(app.current.app, app.current.tab, app.current.view, app.current.page + '/' + app.current.filter + '/' + app.current.search); + appGoto(app.current.app, app.current.tab, app.current.view, app.current.page + '/' + app.current.filter + '/' + app.current.sort + '/' + app.current.search); } function saveQueue() { @@ -3161,7 +3170,7 @@ function addFilterLetter(x) { default: filter = event.target.innerText; } - appGoto(app.current.app, app.current.tab, app.current.view, '0/' + filter + '/' + app.current.search); + appGoto(app.current.app, app.current.tab, app.current.view, '0/' + filter + '/' + app.current.sort + '/' + app.current.search); }, false); } @@ -3190,7 +3199,7 @@ function addTagList(el, list) { } function gotoTagList() { - appGoto(app.current.app, app.current.tab, app.current.view, '0/-/'); + appGoto(app.current.app, app.current.tab, app.current.view, '0/-/-/'); } function openModal(modal) { diff --git a/src/main.c b/src/main.c index c50ae96..d8fdb3b 100644 --- a/src/main.c +++ b/src/main.c @@ -207,8 +207,9 @@ int main(int argc, char **argv) { #ifdef DEBUG printf("Debug flag enabled, setting loglevel to debug\n"); config.loglevel = 3; - loglevel = config.loglevel; #endif + printf("Setting loglevel to %ld\n", config.loglevel); + loglevel = config.loglevel; signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); diff --git a/src/mpd_client.c b/src/mpd_client.c index 7be9ee3..c120796 100644 --- a/src/mpd_client.c +++ b/src/mpd_client.c @@ -219,13 +219,13 @@ static void mpd_client_api(t_config *config, t_mpd_state *mpd_state, void *arg_r unsigned int uint_buf1, uint_buf2, uint_rc; int je, int_buf1, int_rc; float float_buf; - bool bool_buf; + bool bool_buf, rc; char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4; #ifdef DEBUG struct timespec start, end; #endif - LOG_VERBOSE() printf("API request: %.*s\n", request->length, request->data); + LOG_VERBOSE() printf("API request (%ld): %.*s\n", request->conn_id, request->length, request->data); #ifdef DEBUG clock_gettime(CLOCK_MONOTONIC_RAW, &start); @@ -318,20 +318,21 @@ static void mpd_client_api(t_config *config, t_mpd_state *mpd_state, void *arg_r len = snprintf(buffer, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); break; case MPD_API_SMARTPLS_UPDATE_ALL: - uint_rc = mpd_client_smartpls_update_all(config, mpd_state); - if (uint_rc == 0) + rc = mpd_client_smartpls_update_all(config, mpd_state); + if (rc == true) len = snprintf(buffer, MAX_SIZE, "{\"type\": \"result\", \"data\": \"Smart Playlists updated\"}"); else len = snprintf(buffer, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Smart Playlists update failed\"}"); break; case MPD_API_SMARTPLS_SAVE: je = json_scanf(request->data, request->length, "{data: {type: %Q}}", &p_charbuf1); - len = 1; + len = 0; + rc = false; if (je == 1) { if (strcmp(p_charbuf1, "sticker") == 0) { je = json_scanf(request->data, request->length, "{data: {playlist: %Q, sticker: %Q, maxentries: %d}}", &p_charbuf2, &p_charbuf3, &int_buf1); if (je == 3) { - len = mpd_client_smartpls_save(config, mpd_state, p_charbuf1, p_charbuf2, p_charbuf3, NULL, int_buf1, 0); + rc = mpd_client_smartpls_save(config, mpd_state, p_charbuf1, p_charbuf2, p_charbuf3, NULL, int_buf1, 0); free(p_charbuf2); free(p_charbuf3); } @@ -339,14 +340,14 @@ static void mpd_client_api(t_config *config, t_mpd_state *mpd_state, void *arg_r else if (strcmp(p_charbuf1, "newest") == 0) { je = json_scanf(request->data, request->length, "{data: {playlist: %Q, timerange: %d}}", &p_charbuf2, &int_buf1); if (je == 2) { - len = mpd_client_smartpls_save(config, mpd_state, p_charbuf1, p_charbuf2, NULL, NULL, 0, int_buf1); + rc = mpd_client_smartpls_save(config, mpd_state, p_charbuf1, p_charbuf2, NULL, NULL, 0, int_buf1); free(p_charbuf2); } } else if (strcmp(p_charbuf1, "search") == 0) { je = json_scanf(request->data, request->length, "{data: {playlist: %Q, tag: %Q, searchstr: %Q}}", &p_charbuf2, &p_charbuf3, &p_charbuf4); if (je == 3) { - len = mpd_client_smartpls_save(config, mpd_state, p_charbuf1, p_charbuf2, p_charbuf3, p_charbuf4, 0, 0); + rc = mpd_client_smartpls_save(config, mpd_state, p_charbuf1, p_charbuf2, p_charbuf3, p_charbuf4, 0, 0); free(p_charbuf2); free(p_charbuf3); free(p_charbuf4); @@ -354,10 +355,12 @@ static void mpd_client_api(t_config *config, t_mpd_state *mpd_state, void *arg_r } free(p_charbuf1); } - if (len == 0) + if (rc == true) { len = snprintf(buffer, MAX_SIZE, "{\"type\": \"result\", \"data\": \"ok\"}"); - else + } + else { len = snprintf(buffer, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Saving playlist failed\"}"); + } break; case MPD_API_SMARTPLS_GET: je = json_scanf(request->data, request->length, "{data: {playlist: %Q}}", &p_charbuf1); @@ -2372,7 +2375,7 @@ static int mpd_client_search_adv(t_config *config, t_mpd_state *mpd_state, char RETURN_ERROR_AND_RECOVER("mpd_search_add_expression"); if (strcmp(plist, "") == 0) { - if (sort != NULL && strcmp(sort, "") != 0 && mpd_state->feat_tags == true) { + if (sort != NULL && strcmp(sort, "") != 0 && strcmp(sort, "-") != 0 && mpd_state->feat_tags == true) { if (mpd_search_add_sort_name(mpd_state->conn, sort, sortdesc) == false) RETURN_ERROR_AND_RECOVER("mpd_search_add_sort_name"); } @@ -2636,7 +2639,7 @@ static bool mpd_client_smartpls_save(t_config *config, t_mpd_state *mpd_state, c printf("Error renaming file from %s to %s\n", tmp_file, pl_file); return false; } - else if (mpd_client_smartpls_update_sticker(mpd_state, playlist, tag, maxentries) == 1) { + else if (mpd_client_smartpls_update_sticker(mpd_state, playlist, tag, maxentries) == false) { printf("Update of smart playlist %s failed.\n", playlist); return false; } @@ -2650,7 +2653,7 @@ static bool mpd_client_smartpls_save(t_config *config, t_mpd_state *mpd_state, c printf("Error renaming file from %s to %s\n", tmp_file, pl_file); return false; } - else if (mpd_client_smartpls_update_newest(config, mpd_state, playlist, timerange) == 1) { + else if (mpd_client_smartpls_update_newest(config, mpd_state, playlist, timerange) == false) { printf("Update of smart playlist %s failed.\n", playlist); return false; } @@ -2664,7 +2667,7 @@ static bool mpd_client_smartpls_save(t_config *config, t_mpd_state *mpd_state, c printf("Error renaming file from %s to %s\n", tmp_file, pl_file); return false; } - else if (mpd_client_smartpls_update_search(config, mpd_state, playlist, tag, searchstr) == 1) { + else if (mpd_client_smartpls_update_search(config, mpd_state, playlist, tag, searchstr) == false) { printf("Update of smart playlist %s failed.\n", playlist); return false; } @@ -2703,29 +2706,38 @@ static bool mpd_client_smartpls_update_all(t_config *config, t_mpd_state *mpd_st if (strcmp(smartpltype, "sticker") == 0) { je = json_scanf(content, strlen(content), "{sticker: %Q, maxentries: %d}", &p_charbuf1, &int_buf1); if (je == 2) { - mpd_client_smartpls_update_sticker(mpd_state, ent->d_name, p_charbuf1, int_buf1); + if (mpd_client_smartpls_update_sticker(mpd_state, ent->d_name, p_charbuf1, int_buf1) == false) { + printf("Update of smart playlist %s failed.\n", ent->d_name); + } free(p_charbuf1); } - else + else { printf("Can't parse smart playlist file %s\n", filename); + } } else if (strcmp(smartpltype, "newest") == 0) { je = json_scanf(content, strlen(content), "{timerange: %d}", &int_buf1); if (je == 1) { - mpd_client_smartpls_update_newest(config, mpd_state, ent->d_name, int_buf1); + if (mpd_client_smartpls_update_newest(config, mpd_state, ent->d_name, int_buf1) == false) { + printf("Update of smart playlist %s failed.\n", ent->d_name); + } + } + else { + printf("Can't parse smart playlist file %s\n", filename); } - else - printf("Can't parse smart playlist file %s\n", filename); } else if (strcmp(smartpltype, "search") == 0) { je = json_scanf(content, strlen(content), "{tag: %Q, searchstr: %Q}", &p_charbuf1, &p_charbuf2); if (je == 2) { - mpd_client_smartpls_update_search(config, mpd_state, ent->d_name, p_charbuf1, p_charbuf2); + if (mpd_client_smartpls_update_search(config, mpd_state, ent->d_name, p_charbuf1, p_charbuf2) == false) { + printf("Update of smart playlist %s failed.\n", ent->d_name); + } free(p_charbuf1); free(p_charbuf2); } - else + else { printf("Can't parse smart playlist file %s\n", filename); + } } free(smartpltype); free(content); @@ -2775,7 +2787,7 @@ static bool mpd_client_smartpls_update_search(t_config *config, t_mpd_state *mpd else { mpd_client_search(config, mpd_state, buffer, searchstr, tag, playlist, 0); } - LOG_INFO() printf("Updated %s\n", playlist); + LOG_INFO() printf("Updated smart playlist %s\n", playlist); return true; } @@ -2841,7 +2853,7 @@ static bool mpd_client_smartpls_update_sticker(t_mpd_state *mpd_state, const cha current = current->next; } list_free(&add_list); - LOG_INFO() printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max); + LOG_INFO() printf("Updated smart playlist %s with %ld songs, minValue: %ld\n", playlist, i, value_max); return true; } @@ -2871,7 +2883,7 @@ static bool mpd_client_smartpls_update_newest(t_config *config, t_mpd_state *mpd snprintf(searchstr, 20, "%d", value_max); mpd_client_search(config, mpd_state, buffer, searchstr, "modified-since", playlist, 0); } - LOG_INFO() printf("Updated %s\n", playlist); + LOG_INFO() printf("Updated smart playlist %s\n", playlist); } return true; } diff --git a/src/web_server.c b/src/web_server.c index 8ac139f..6a8696a 100644 --- a/src/web_server.c +++ b/src/web_server.c @@ -56,7 +56,7 @@ bool web_server_init(void *arg_mgr, t_config *config) { struct mg_bind_opts bind_opts_http; const char *err_https; const char *err_http; - + t_user_data *user_data = (t_user_data*)malloc(sizeof(t_user_data)); user_data->config = config; user_data->conn_id = 1; @@ -251,7 +251,7 @@ static void ev_handler_redirect(struct mg_connection *nc, int ev, void *ev_data) static bool handle_api(long conn_id, const char *request_body, int request_len) { char *cmd; - LOG_VERBOSE() printf("API request: %.*s\n", request_len, request_body); + LOG_VERBOSE() printf("API request (%ld): %.*s\n", conn_id, request_len, request_body); const int je = json_scanf(request_body, request_len, "{cmd: %Q}", &cmd); if (je < 1) return false;