From 2926881487b08209c8da5f7ce1250eedef0ea534 Mon Sep 17 00:00:00 2001 From: jcorporation Date: Tue, 17 Sep 2024 22:18:41 +0200 Subject: [PATCH] Feat: Work actions in album detail view --- CHANGELOG.md | 7 +++++ htdocs/js/album.js | 19 +++++++------ htdocs/js/apidoc.js | 46 +++++++++++++++++++++---------- htdocs/js/clickActions.js | 3 ++ htdocs/js/contextMenu.js | 17 ++++++------ htdocs/js/contextMenuOffcanvas.js | 5 ++-- htdocs/js/customElements.js | 9 ++++++ htdocs/js/globales.js | 17 ++++++------ htdocs/js/playlists.js | 18 ++++++++---- htdocs/js/queue.js | 18 ++++++++---- htdocs/js/settings.js | 4 +++ htdocs/js/views.js | 10 ++++++- htdocs/js/viewsTables.js | 18 ++++++++---- src/compile_time.h.in | 1 - src/lib/api.h | 12 ++++---- src/lib/mympd_state.c | 1 - src/lib/mympd_state.h | 1 - src/lib/sds_extras.c | 4 ++- src/mpd_client/search.c | 11 ++++---- src/mpd_client/search.h | 5 ++-- src/mympd_api/mympd_api_handler.c | 46 ++++++++++++++++++------------- src/mympd_api/playlists.c | 35 +++++++++++++---------- src/mympd_api/playlists.h | 12 ++++---- src/mympd_api/queue.c | 35 ++++++++++++----------- src/mympd_api/queue.h | 12 ++++---- src/mympd_api/settings.c | 14 ---------- 26 files changed, 227 insertions(+), 153 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6956573c1..851f7da70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,12 @@ All scripts in the mympd-scripts repository are updated accordingly, do not forg - MYMPD_API_QUEUE_INSERT_ALBUM_RANGE: new - MYMPD_API_QUEUE_REPLACE_ALBUM_RANGE: new - MYMPD_API_SETTINGS_GET: returns now available sticker types +- MYMPD_API_QUEUE_APPEND_ALBUM_DISC renamed to MYMPD_API_QUEUE_APPEND_ALBUM_TAG +- MYMPD_API_QUEUE_INSERT_ALBUM_DISC renamed to MYMPD_API_QUEUE_INSERT_ALBUM_TAG +- MYMPD_API_QUEUE_REPLACE_ALBUM_DISC renamed to MYMPD_API_QUEUE_REPLACE_ALBUM_TAG +- MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_DISC renamed to MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_TAG +- MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_DISC renamed to MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_TAG +- MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_DISC renamed to MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_TAG ### Changelog @@ -52,6 +58,7 @@ All scripts in the mympd-scripts repository are updated accordingly, do not forg - Feat: Add list view - Feat: Add widgets for home screen - Feat: Sort list of playlists by name or last-modified +- Feat: Work actions in album detail view - Upd: Playlist pictures are moved in a separate folder `/var/lib/mympd/pics/playlists` - Upd: Latest libmympdclient based on libmpdclient master - Upd: Hide advanced search by default diff --git a/htdocs/js/album.js b/htdocs/js/album.js index d4279a49a..eae932f5c 100644 --- a/htdocs/js/album.js +++ b/htdocs/js/album.js @@ -6,32 +6,33 @@ /** @module album_js */ /** - * Handles single disc actions + * Handles album filtered by tag * @param {string} action action to perform * @param {string} albumId the album id - * @param {string} disc disc number as string + * @param {string} tag MPD tag + * @param {string} value MPD tag value * @returns {void} */ //eslint-disable-next-line no-unused-vars -function addAlbumDisc(action, albumId, disc) { +function addAlbumTag(action, albumId, tag, value) { switch(action) { case 'appendQueue': - appendQueue('disc', [albumId, disc]); + appendQueue(tag, [albumId, value]); break; case 'appendPlayQueue': - appendPlayQueue('disc', [albumId, disc]); + appendPlayQueue(tag, [albumId, value]); break; case 'insertAfterCurrentQueue': - insertAfterCurrentQueue('disc', [albumId, disc]); + insertAfterCurrentQueue(tag, [albumId, value]); break; case 'replaceQueue': - replaceQueue('disc', [albumId, disc]); + replaceQueue(tag, [albumId, value]); break; case 'replacePlayQueue': - replacePlayQueue('disc', [albumId, disc]); + replacePlayQueue(tag, [albumId, value]); break; case 'addPlaylist': - showAddToPlaylist('disc', [albumId, disc]); + showAddToPlaylist(tag, [albumId, value]); break; default: logError('Invalid action: ' + action); diff --git a/htdocs/js/apidoc.js b/htdocs/js/apidoc.js index 9f19d4c81..d73cad06e 100644 --- a/htdocs/js/apidoc.js +++ b/htdocs/js/apidoc.js @@ -213,6 +213,16 @@ const APIparams = { "type": APItypes.int, "example": 1, "desc": "End position (excluding), use -1 for open end" + }, + "tag": { + "type": APItypes.string, + "example": "Disc", + "desc": "MPD tag" + }, + "tagValue": { + "type": APItypes.string, + "example": "1", + "desc": "MPD tag value" } }; @@ -510,11 +520,12 @@ const APImethods = { "play": APIparams.play } }, - "MYMPD_API_QUEUE_INSERT_ALBUM_DISC": { - "desc": "Inserts one discs from an album to distinct position in the queue.", + "MYMPD_API_QUEUE_INSERT_ALBUM_TAG": { + "desc": "Inserts songs from an album with specified tag value to distinct position in the queue.", "params": { "albumid": APIparams.albumid, - "disc": APIparams.disc, + "tag": APIparams.tag, + "value": APIparams.tagValue, "to": APIparams.to, "whence": APIparams.whence, "play": APIparams.play @@ -584,11 +595,12 @@ const APImethods = { "play": APIparams.play } }, - "MYMPD_API_QUEUE_APPEND_ALBUM_DISC": { - "desc": "Appends on disc from an album to the queue.", + "MYMPD_API_QUEUE_APPEND_ALBUM_TAG": { + "desc": "Appends songs from an album to the queue with specified tag value.", "params": { "albumid": APIparams.albumid, - "disc": APIparams.disc, + "tag": APIparams.tag, + "value": APIparams.tagValue, "play": APIparams.play } }, @@ -654,11 +666,12 @@ const APImethods = { "play": APIparams.play } }, - "MYMPD_API_QUEUE_REPLACE_ALBUM_DISC": { - "desc": "Replaces the queue with one disc from an album.", + "MYMPD_API_QUEUE_REPLACE_ALBUM_TAG": { + "desc": "Replaces the queue with songs from an album with specified tag value.", "params": { "albumid": APIparams.albumid, - "disc": APIparams.disc, + "tag": APIparams.tag, + "value": APIparams.tagValue, "play": APIparams.play } }, @@ -791,12 +804,13 @@ const APImethods = { "albumids": APIparams.albumids } }, - "MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_DISC": { + "MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_TAG": { "desc": "Appends one disc from an album to the playlist.", "params": { "plist": APIparams.plist, "albumid": APIparams.albumid, - "disc": APIparams.disc + "tag": APIparams.tag, + "value": APIparams.tagValue } }, "MYMPD_API_PLAYLIST_CONTENT_INSERT_URIS": { @@ -815,12 +829,13 @@ const APImethods = { "to": APIparams.to } }, - "MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_DISC": { + "MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_TAG": { "desc": "Inserts one disc from an album to the playlist.", "params": { "plist": APIparams.plist, "albumid": APIparams.albumid, - "disc": APIparams.disc, + "tag": APIparams.tag, + "value": APIparams.tagValue, "to": APIparams.to } }, @@ -838,12 +853,13 @@ const APImethods = { "albumids": APIparams.albumids } }, - "MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_DISC": { + "MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_TAG": { "desc": "Replaces the playlist content with one disc from an album.", "params": { "plist": APIparams.plist, "albumid": APIparams.albumid, - "disc": APIparams.disc + "tag": APIparams.tag, + "value": APIparams.tagValue } }, "MYMPD_API_PLAYLIST_CONTENT_INSERT_SEARCH": { diff --git a/htdocs/js/clickActions.js b/htdocs/js/clickActions.js index f0ca22df7..beec91d38 100644 --- a/htdocs/js/clickActions.js +++ b/htdocs/js/clickActions.js @@ -62,6 +62,9 @@ function clickQuickPlay(target) { case 'disc': uri.push(getData(dataNode, 'AlbumId'), getData(dataNode, 'Disc')); break; + case 'work': + uri.push(getData(dataNode, 'AlbumId'), getData(dataNode, 'Work')); + break; default: uri.push(getData(dataNode, 'uri')); } diff --git a/htdocs/js/contextMenu.js b/htdocs/js/contextMenu.js index 6c8101f48..b5c14a801 100644 --- a/htdocs/js/contextMenu.js +++ b/htdocs/js/contextMenu.js @@ -203,23 +203,24 @@ function addMenuItemsNavbarActions(target, popoverBody) { * @param {HTMLElement} contextMenuBody element to append the menu items * @returns {void} */ -function addMenuItemsDiscActions(target, contextMenuTitle, contextMenuBody) { +function addMenuItemsAlbumTagActions(target, contextMenuTitle, contextMenuBody) { const dataNode = target.parentNode.parentNode; - const disc = getData(dataNode, 'Disc'); + const type = getData(dataNode, 'type'); + const value = getData(dataNode, ucFirst(type)); const albumId = getData(dataNode, 'AlbumId'); - addMenuItem(contextMenuBody, {"cmd": "addAlbumDisc", "options": ["appendQueue", albumId, disc]}, 'Append to queue'); - addMenuItem(contextMenuBody, {"cmd": "addAlbumDisc", "options": ["appendPlayQueue", albumId, disc]}, 'Append to queue and play'); + addMenuItem(contextMenuBody, {"cmd": "addAlbumTag", "options": ["appendQueue", albumId, type, value]}, 'Append to queue'); + addMenuItem(contextMenuBody, {"cmd": "addAlbumTag", "options": ["appendPlayQueue", albumId, type, value]}, 'Append to queue and play'); if (features.featWhence === true && currentState.currentSongId !== -1) { - addMenuItem(contextMenuBody, {"cmd": "addAlbumDisc", "options": ["insertAfterCurrentQueue", albumId, disc]}, 'Insert after current playing song'); + addMenuItem(contextMenuBody, {"cmd": "addAlbumTag", "options": ["insertAfterCurrentQueue", albumId, type, value]}, 'Insert after current playing song'); } - addMenuItem(contextMenuBody, {"cmd": "addAlbumDisc", "options": ["replaceQueue", albumId, disc]}, 'Replace queue'); - addMenuItem(contextMenuBody, {"cmd": "addAlbumDisc", "options": ["replacePlayQueue", albumId, disc]}, 'Replace queue and play'); + addMenuItem(contextMenuBody, {"cmd": "addAlbumTag", "options": ["replaceQueue", albumId, type, value]}, 'Replace queue'); + addMenuItem(contextMenuBody, {"cmd": "addAlbumTag", "options": ["replacePlayQueue", albumId, type, value]}, 'Replace queue and play'); if (features.featPlaylists === true) { addDivider(contextMenuBody); - addMenuItem(contextMenuBody, {"cmd": "addAlbumDisc", "options": ["addPlaylist", albumId, disc]}, 'Add to playlist'); + addMenuItem(contextMenuBody, {"cmd": "addAlbumTag", "options": ["addPlaylist", albumId, type, value]}, 'Add to playlist'); } } diff --git a/htdocs/js/contextMenuOffcanvas.js b/htdocs/js/contextMenuOffcanvas.js index 648c5aaf3..b07c12543 100644 --- a/htdocs/js/contextMenuOffcanvas.js +++ b/htdocs/js/contextMenuOffcanvas.js @@ -39,8 +39,9 @@ function showContextMenuOffcanvas(target, contextMenuType) { createContextMenuOffcanvas(target, contextMenuEl, contextMenuType, createMenuViewSettings, undefined); break; case 'disc': - //disc actions in album details view - createContextMenuOffcanvas(target, contextMenuEl, contextMenuType, addMenuItemsDiscActions, undefined); + case 'work': + //disc and work actions in album details view + createContextMenuOffcanvas(target, contextMenuEl, contextMenuType, addMenuItemsAlbumTagActions, undefined); break; case 'homeIcon': //home card icon actions diff --git a/htdocs/js/customElements.js b/htdocs/js/customElements.js index 7b9a45772..6f2bdfe27 100644 --- a/htdocs/js/customElements.js +++ b/htdocs/js/customElements.js @@ -14,6 +14,7 @@ function createPreGeneratedElements() { pEl.selectAllBtn = elCreateText('button', {"type": "button", "href": "#", "class": ["btn", "mi", "border-0"], "data-title-phrase": "Select all"}, 'radio_button_unchecked'); pEl.actionsBtn = elCreateText('a', {"data-action": "popover", "href": "#", "class": ["mi", "color-darkgrey"], "data-title-phrase": "Actions"}, ligatures['more']); pEl.actionsDiscBtn = elCreateText('a', {"data-action": "popover", "data-contextmenu": "disc", "href": "#", "class": ["mi", "color-darkgrey"], "data-title-phrase": "Actions"}, ligatures['more']); + pEl.actionsWorkBtn = elCreateText('a', {"data-action": "popover", "data-contextmenu": "work", "href": "#", "class": ["mi", "color-darkgrey"], "data-title-phrase": "Actions"}, ligatures['more']); pEl.removeBtn = elCreateText('a', {"data-action": "quickRemove", "href": "#", "class": ["mi", "color-darkgrey", "me-1"], "data-title-phrase": "Remove"}, 'clear'); pEl.playBtn = elCreateText('a', {"data-action": "quickPlay", "href": "#", "class": ["mi", "color-darkgrey", "me-1"], "data-title-phrase": "Quick play"}, 'play_arrow'); pEl.showSongsBtn = elCreateText('a', {"data-action": "showSongsByTag", "class": ["mi", "color-darkgrey", "me-1"], "href": "#", "data-title-phrase": "Show songs"}, 'music_note'); @@ -59,13 +60,21 @@ function createPreGeneratedElements() { pEl.actionMenuDisc = [ pEl.actionsDiscBtn ]; + pEl.actionMenuWork = [ + pEl.actionsWorkBtn + ]; pEl.actionMenuDiscPlay = [ pEl.playBtn, pEl.actionsDiscBtn ]; + pEl.actionMenuWorkPlay = [ + pEl.playBtn, + pEl.actionsWorkBtn + ]; pEl.actionIcons = pEl.actionMenu; pEl.actionDiscIcons = pEl.actionMenuDisc; + pEl.actionWorkIcons = pEl.actionMenuWork; pEl.actionQueueIcons = pEl.actionMenu; pEl.actionJukeboxIcons = pEl.actionMenu; pEl.actionPlaylistDetailIcons = pEl.actionMenu; diff --git a/htdocs/js/globales.js b/htdocs/js/globales.js index a6d88de51..4adbda55a 100644 --- a/htdocs/js/globales.js +++ b/htdocs/js/globales.js @@ -413,13 +413,6 @@ const settingsFields = { "title": "Enforce disc tag", "form": "modalSettingsTagsFrm", "help": "helpSettingsTagDiscEmptyIsFirst" - }, - "showWorkTagAlbumDetail": { - "defaultValue": defaults["MYMPD_SHOW_WORK_TAG_ALBUM_DETAIL"], - "inputType": "checkbox", - "title": "Show work in album detail", - "form": "modalSettingsTagsFrm", - "help": "helpSettingsShowWorkTagAlbumDetail" } }; @@ -893,6 +886,13 @@ const settingsWebuiFields = { "title": "Album list sort", "form": "modalSettingsSortFrm", "help": "helpSettingsAlbumListSort" + }, + "showWorkTagAlbumDetail": { + "defaultValue": false, + "inputType": "checkbox", + "title": "Show work in album detail", + "form": "modalSettingsTagsFrm", + "help": "helpSettingsShowWorkTagAlbumDetail" } }; @@ -1724,7 +1724,8 @@ const typeFriendly = { 'appGoto': 'View', 'webradio': 'Webradio', 'viewSettings': 'View settings', - 'disc': 'Disc' + 'disc': 'Disc', + 'work': 'Work' }; const friendlyActions = { diff --git a/htdocs/js/playlists.js b/htdocs/js/playlists.js index f539fea83..35b1b7abd 100644 --- a/htdocs/js/playlists.js +++ b/htdocs/js/playlists.js @@ -207,9 +207,11 @@ function appendPlaylist(type, uris, plist, callback) { }, callback, true); break; case 'disc': - sendAPI("MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_DISC", { + case 'work': + sendAPI("MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_TAG", { "albumid": uris[0], - "disc": uris[1].toString(), + "tag": type, + "value": uris[1].toString(), "plist": plist }, callback, true); break; @@ -263,9 +265,11 @@ function insertPlaylist(type, uris, plist, to, callback) { }, callback, true); break; case 'disc': - sendAPI("MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_DISC", { + case 'work': + sendAPI("MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_TAG", { "albumid": uris[0], - "disc": uris[1].toString(), + "tag": type, + "value": uris[1].toString(), "plist": plist, "to": to }, callback, true); @@ -316,9 +320,11 @@ function replacePlaylist(type, uris, plist, callback) { }, callback, true); break; case 'disc': - sendAPI("MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_DISC", { + case 'work': + sendAPI("MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_TAG", { "albumid": uris[0], - "disc": uris[1].toString(), + "tag": type, + "value": uris[1].toString(), "plist": plist }, callback, true); break; diff --git a/htdocs/js/queue.js b/htdocs/js/queue.js index 5238f3f2c..87541c542 100644 --- a/htdocs/js/queue.js +++ b/htdocs/js/queue.js @@ -154,10 +154,12 @@ function _appendQueue(type, uris, play, callback) { }, callback, true); break; case 'disc': + case 'work': //disc is limited to one at a time - sendAPI("MYMPD_API_QUEUE_APPEND_ALBUM_DISC", { + sendAPI("MYMPD_API_QUEUE_APPEND_ALBUM_TAG", { "albumid": uris[0], - "disc": uris[1].toString(), + "tag": type, + "value": uris[1].toString(), "play": play }, callback, true); break; @@ -255,9 +257,11 @@ function insertQueue(type, uris, to, whence, play, callback) { }, callback, true); break; case 'disc': - sendAPI("MYMPD_API_QUEUE_INSERT_ALBUM_DISC", { + case 'work': + sendAPI("MYMPD_API_QUEUE_INSERT_ALBUM_TAG", { "albumid": uris[0], - "disc": uris[1].toString(), + "tag": type, + "value": uris[1].toString(), "to": to, "whence": whence, "play": play @@ -343,9 +347,11 @@ function _replaceQueue(type, uris, play, callback) { }, callback, true); break; case 'disc': - sendAPI("MYMPD_API_QUEUE_REPLACE_ALBUM_DISC", { + case 'work': + sendAPI("MYMPD_API_QUEUE_REPLACE_ALBUM_TAG", { "albumid": uris[0], - "disc": uris[1].toString(), + "tag": type, + "value": uris[1].toString(), "play": play }, callback, true); break; diff --git a/htdocs/js/settings.js b/htdocs/js/settings.js index 9f5b1e76d..6d40e42a7 100644 --- a/htdocs/js/settings.js +++ b/htdocs/js/settings.js @@ -241,6 +241,7 @@ function parseSettings(obj) { { pEl.actionIcons = pEl.actionMenuPlay; pEl.actionDiscIcons = pEl.actionMenuDiscPlay; + pEl.actionWorkIcons = pEl.actionMenuWorkPlay; pEl.actionQueueIcons = pEl.actionMenuRemove; pEl.actionJukeboxIcons = pEl.actionMenuPlayRemove; pEl.actionPlaylistDetailIcons = pEl.actionMenuPlayRemove; @@ -249,6 +250,7 @@ function parseSettings(obj) { else if (settings.webuiSettings.quickPlayButton === true) { pEl.actionIcons = pEl.actionMenuPlay; pEl.actionDiscIcons = pEl.actionMenuDiscPlay; + pEl.actionWorkIcons = pEl.actionMenuWorkPlay; pEl.actionQueueIcons = pEl.actionMenu; pEl.actionJukeboxIcons = pEl.actionMenuPlay; pEl.actionPlaylistDetailIcons = pEl.actionMenuPlay; @@ -257,6 +259,7 @@ function parseSettings(obj) { else if (settings.webuiSettings.quickRemoveButton === true) { pEl.actionIcons = pEl.actionMenu; pEl.actionDiscIcons = pEl.actionMenuDisc; + pEl.actionWorkIcons = pEl.actionMenuWork; pEl.actionQueueIcons = pEl.actionMenuRemove; pEl.actionJukeboxIcons = pEl.actionMenuRemove; pEl.actionPlaylistDetailIcons = pEl.actionMenuRemove; @@ -265,6 +268,7 @@ function parseSettings(obj) { else { pEl.actionIcons = pEl.actionMenu; pEl.actionDiscIcons = pEl.actionMenuDisc; + pEl.actionWorkIcons = pEl.actionMenuWork; pEl.actionQueueIcons = pEl.actionMenu; pEl.actionJukeboxIcons = pEl.actionMenu; pEl.actionPlaylistDetailIcons = pEl.actionMenu; diff --git a/htdocs/js/views.js b/htdocs/js/views.js index e2dfd67c0..609d88f60 100644 --- a/htdocs/js/views.js +++ b/htdocs/js/views.js @@ -286,7 +286,15 @@ function getActionLinks(userData) { ? pEl.actionMenuBrowseDatabaseTagSongsStickers : pEl.actionMenuBrowseDatabaseTagSongs; case 'BrowseDatabaseAlbumDetail': - return userData === 'disc' ? pEl.actionDiscIcons : pEl.actionIcons; + if (userData === 'disc') { + return pEl.actionDiscIcons; + } + else if (userData === 'work') { + return pEl.actionWorkIcons; + } + else { + return pEl.actionIcons; + } default: return pEl.actionIcons; } diff --git a/htdocs/js/viewsTables.js b/htdocs/js/viewsTables.js index af3b04709..6443709c8 100644 --- a/htdocs/js/viewsTables.js +++ b/htdocs/js/viewsTables.js @@ -180,22 +180,30 @@ function addDiscRow(disc, albumId, colspan) { * @returns {boolean} true if work row should be shown, else false */ function showWorkRow(view) { - return view === 'BrowseDatabaseAlbumDetail'; + return view === 'BrowseDatabaseAlbumDetail' && + settings.webuiSettings.showWorkTagAlbumDetail; } /** * Adds a row with the work to the table. * @param {string} work The work name + * @param {string} albumId the albumid * @param {number} colspan column count * @returns {HTMLElement} the created row */ -function addWorkRow(work, colspan) { +function addWorkRow(work, albumId, colspan) { + const actionTd = elCreateEmpty('td', {"data-col": "Action"}); + addActionLinks(actionTd, 'work'); const row = elCreateNodes('tr', {"class": ["not-clickable"]}, [ elCreateNode('td', {}, elCreateText('span', {"class": ["mi"]}, 'music_note') ), - elCreateText('td', {"colspan": (colspan)}, work), + elCreateText('td', {"colspan": (colspan - 1)}, work), + actionTd ]); + setData(row, 'Work', work); + setData(row, 'AlbumId', albumId); + setData(row, 'type', 'work'); return row; } @@ -252,7 +260,7 @@ function updateTable(obj, list, perRowCallback, createRowCellsCallback) { } if (showWorkRow(list) && lastWork !== '') { - const row = addWorkRow(lastWork, colspan); + const row = addWorkRow(lastWork, obj.result.AlbumId, colspan); if (z < tr.length) { replaceTblRow(mode, tr[z], row); } @@ -280,7 +288,7 @@ function updateTable(obj, list, perRowCallback, createRowCellsCallback) { if (showWorkRow(list) && obj.result.data[0].Work !== undefined && lastWork !== obj.result.data[i].Work) { - const row = addWorkRow(obj.result.data[i].Work, colspan); + const row = addWorkRow(obj.result.data[i].Work, obj.result.AlbumId, colspan); if (i + z < tr.length) { replaceTblRow(mode, tr[i + z], row); } else { diff --git a/src/compile_time.h.in b/src/compile_time.h.in index acbf7ae0a..8eb256f9b 100644 --- a/src/compile_time.h.in +++ b/src/compile_time.h.in @@ -215,7 +215,6 @@ extern struct t_mympd_queue *mympd_api_queue; "{\"ligature\":\"library_music\",\"title\":\"Browse\",\"options\":[\"Browse\"]},"\ "{\"ligature\":\"search\",\"title\":\"Search\",\"options\":[\"Search\"]}]" #define MYMPD_TAG_DISC_EMPTY_IS_FIRST true -#define MYMPD_SHOW_WORK_TAG_ALBUM_DETAIL false //http headers #define EXTRA_HEADERS_CACHE "Cache-Control: max-age=604800\r\n" diff --git a/src/lib/api.h b/src/lib/api.h index a6d9b40c2..9839b87af 100644 --- a/src/lib/api.h +++ b/src/lib/api.h @@ -115,7 +115,7 @@ X(MYMPD_API_PLAYLIST_CONTENT_APPEND_SEARCH) \ X(MYMPD_API_PLAYLIST_CONTENT_APPEND_URIS) \ X(MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUMS) \ - X(MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_DISC) \ + X(MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_TAG) \ X(MYMPD_API_PLAYLIST_CONTENT_CLEAR) \ X(MYMPD_API_PLAYLIST_CONTENT_DEDUP) \ X(MYMPD_API_PLAYLIST_CONTENT_DEDUP_ALL) \ @@ -123,14 +123,14 @@ X(MYMPD_API_PLAYLIST_CONTENT_INSERT_SEARCH) \ X(MYMPD_API_PLAYLIST_CONTENT_INSERT_URIS) \ X(MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUMS) \ - X(MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_DISC) \ + X(MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_TAG) \ X(MYMPD_API_PLAYLIST_CONTENT_LIST) \ X(MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION) \ X(MYMPD_API_PLAYLIST_CONTENT_MOVE_TO_PLAYLIST) \ X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_SEARCH) \ X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_URIS) \ X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUMS) \ - X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_DISC) \ + X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_TAG) \ X(MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS) \ X(MYMPD_API_PLAYLIST_CONTENT_RM_RANGE) \ X(MYMPD_API_PLAYLIST_CONTENT_SHUFFLE) \ @@ -155,7 +155,7 @@ X(MYMPD_API_QUEUE_APPEND_URI_TAGS) \ X(MYMPD_API_QUEUE_APPEND_URI_RESUME) \ X(MYMPD_API_QUEUE_APPEND_ALBUMS) \ - X(MYMPD_API_QUEUE_APPEND_ALBUM_DISC) \ + X(MYMPD_API_QUEUE_APPEND_ALBUM_TAG) \ X(MYMPD_API_QUEUE_APPEND_ALBUM_RANGE) \ X(MYMPD_API_QUEUE_CLEAR) \ X(MYMPD_API_QUEUE_CROP) \ @@ -167,7 +167,7 @@ X(MYMPD_API_QUEUE_INSERT_URI_TAGS) \ X(MYMPD_API_QUEUE_INSERT_URI_RESUME) \ X(MYMPD_API_QUEUE_INSERT_ALBUMS) \ - X(MYMPD_API_QUEUE_INSERT_ALBUM_DISC) \ + X(MYMPD_API_QUEUE_INSERT_ALBUM_TAG) \ X(MYMPD_API_QUEUE_INSERT_ALBUM_RANGE) \ X(MYMPD_API_QUEUE_MOVE_POSITION) \ X(MYMPD_API_QUEUE_MOVE_RELATIVE) \ @@ -180,7 +180,7 @@ X(MYMPD_API_QUEUE_REPLACE_URI_TAGS) \ X(MYMPD_API_QUEUE_REPLACE_URI_RESUME) \ X(MYMPD_API_QUEUE_REPLACE_ALBUMS) \ - X(MYMPD_API_QUEUE_REPLACE_ALBUM_DISC) \ + X(MYMPD_API_QUEUE_REPLACE_ALBUM_TAG) \ X(MYMPD_API_QUEUE_REPLACE_ALBUM_RANGE) \ X(MYMPD_API_QUEUE_RM_RANGE) \ X(MYMPD_API_QUEUE_RM_IDS) \ diff --git a/src/lib/mympd_state.c b/src/lib/mympd_state.c index 942affcea..39a0d4fd7 100644 --- a/src/lib/mympd_state.c +++ b/src/lib/mympd_state.c @@ -104,7 +104,6 @@ void mympd_state_default(struct t_mympd_state *mympd_state, struct t_config *con mympd_state->navbar_icons = sdsnew(MYMPD_NAVBAR_ICONS); mpd_tags_reset(&mympd_state->smartpls_generate_tag_types); mympd_state->tag_disc_empty_is_first = MYMPD_TAG_DISC_EMPTY_IS_FIRST; - mympd_state->show_work_tag_album_detail = MYMPD_SHOW_WORK_TAG_ALBUM_DETAIL; mympd_state->booklet_name = sdsnew(MYMPD_BOOKLET_NAME); mympd_state->info_txt_name = sdsnew(MYMPD_INFO_TXT_NAME); //mpd shared state diff --git a/src/lib/mympd_state.h b/src/lib/mympd_state.h index 8f4fdef03..999355c0f 100644 --- a/src/lib/mympd_state.h +++ b/src/lib/mympd_state.h @@ -264,7 +264,6 @@ struct t_mympd_state { struct t_lyrics lyrics; //!< lyrics settings sds webui_settings; //!< settings only relevant for webui, saved as string containing json bool tag_disc_empty_is_first; //!< handle empty disc tag as disc one for albums - bool show_work_tag_album_detail; //!< show work tag in album detail view sds booklet_name; //!< name of the booklet files sds info_txt_name; //!< name of album info files struct t_cache album_cache; //!< the album cache created by the mpd_worker thread diff --git a/src/lib/sds_extras.c b/src/lib/sds_extras.c index 0ab830471..7c0713203 100644 --- a/src/lib/sds_extras.c +++ b/src/lib/sds_extras.c @@ -499,7 +499,9 @@ sds sds_replace(sds s, const char *p) { * @return modified sds string */ sds sds_catbool(sds s, bool v) { - return v == true ? sdscatlen(s, "true", 4) : sdscatlen(s, "false", 5); + return v == true + ? sdscatlen(s, "true", 4) + : sdscatlen(s, "false", 5); } /** diff --git a/src/mpd_client/search.c b/src/mpd_client/search.c index 9985ce7ac..a888af3c0 100644 --- a/src/mpd_client/search.c +++ b/src/mpd_client/search.c @@ -162,22 +162,23 @@ sds get_search_expression_album(sds buffer, enum mpd_tag_type tag_albumartist, s } /** - * Creates a mpd search expression to find all songs in one cd of an album + * Creates a mpd search expression to find all songs of specified disc of an album * @param tag_albumartist albumartist tag * @param album mpd_song struct representing the album - * @param disc disc number + * @param tag MPD tag + * @param tag_value MPD tag value * @param album_config album configuration * @return newly allocated sds string */ -sds get_search_expression_album_disc(sds buffer, enum mpd_tag_type tag_albumartist, struct mpd_song *album, - const char *disc, const struct t_albums_config *album_config) +sds get_search_expression_album_tag(sds buffer, enum mpd_tag_type tag_albumartist, struct mpd_song *album, + enum mpd_tag_type tag, const char *tag_value, const struct t_albums_config *album_config) { sdsclear(buffer); buffer = sdscatlen(buffer, "(", 1); buffer = append_search_expression_album(tag_albumartist, album, album_config, buffer); //and for cd buffer = sdscat(buffer, " AND "); - buffer = escape_mpd_search_expression(buffer, "Disc", "==", disc); + buffer = escape_mpd_search_expression(buffer, mpd_tag_name(tag), "==", tag_value); buffer = sdscatlen(buffer, ")", 1); return buffer; } diff --git a/src/mpd_client/search.h b/src/mpd_client/search.h index 486f84f6a..2e57ccef6 100644 --- a/src/mpd_client/search.h +++ b/src/mpd_client/search.h @@ -27,7 +27,8 @@ bool mpd_client_add_search_sort_param(struct t_partition_state *partition_state, bool mpd_client_add_search_group_param(struct mpd_connection *conn, enum mpd_tag_type tag); sds get_search_expression_album(sds buffer, enum mpd_tag_type tag_albumartist, struct mpd_song *album, const struct t_albums_config *album_config); -sds get_search_expression_album_disc(sds buffer, enum mpd_tag_type tag_albumartist, struct mpd_song *album, - const char *disc, const struct t_albums_config *album_config); +sds get_search_expression_album_tag(sds buffer, enum mpd_tag_type tag_albumartist, struct mpd_song *album, + enum mpd_tag_type tag, const char *tag_value, const struct t_albums_config *album_config); sds escape_mpd_search_expression(sds buffer, const char *tag, const char *operator, const char *value); + #endif diff --git a/src/mympd_api/mympd_api_handler.c b/src/mympd_api/mympd_api_handler.c index 1f50b79e6..5ce138763 100644 --- a/src/mympd_api/mympd_api_handler.c +++ b/src/mympd_api/mympd_api_handler.c @@ -1202,29 +1202,33 @@ void mympd_api_handler(struct t_mympd_state *mympd_state, struct t_partition_sta list_clear(&albumids); break; } - case MYMPD_API_QUEUE_APPEND_ALBUM_DISC: - case MYMPD_API_QUEUE_REPLACE_ALBUM_DISC: { + case MYMPD_API_QUEUE_APPEND_ALBUM_TAG: + case MYMPD_API_QUEUE_REPLACE_ALBUM_TAG: { if (json_get_string(request->data, "$.params.albumid", 1, NAME_LEN_MAX, &sds_buf1, vcb_isalnum, &parse_error) == true && - json_get_string(request->data, "$.params.disc", 1, NAME_LEN_MAX, &sds_buf2, vcb_isdigit, &parse_error) == true && + json_get_string(request->data, "$.params.tag", 1, NAME_LEN_MAX, &sds_buf2, vcb_ismpdtag, &parse_error) == true && + json_get_string(request->data, "$.params.value", 1, NAME_LEN_MAX, &sds_buf3, vcb_isname, &parse_error) == true && json_get_bool(request->data, "$.params.play", &bool_buf1, &parse_error) == true) { - rc = (request->cmd_id == MYMPD_API_QUEUE_APPEND_ALBUM_DISC - ? mympd_api_queue_append_album_disc(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, &error) - : mympd_api_queue_replace_album_disc(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, &error)) && + enum mpd_tag_type tag = mpd_tag_name_iparse(sds_buf2); + rc = (request->cmd_id == MYMPD_API_QUEUE_APPEND_ALBUM_TAG + ? mympd_api_queue_append_album_tag(partition_state, &mympd_state->album_cache, sds_buf1, tag, sds_buf3, &error) + : mympd_api_queue_replace_album_tag(partition_state, &mympd_state->album_cache, sds_buf1, tag, sds_buf3, &error)) && mpd_client_queue_check_start_play(partition_state, bool_buf1, &error); response->data = jsonrpc_respond_with_message_or_error(response->data, request->cmd_id, request->id, rc, JSONRPC_FACILITY_QUEUE, "Queue updated", error); } break; } - case MYMPD_API_QUEUE_INSERT_ALBUM_DISC: { + case MYMPD_API_QUEUE_INSERT_ALBUM_TAG: { if (json_get_string(request->data, "$.params.albumid", 1, NAME_LEN_MAX, &sds_buf1, vcb_isalnum, &parse_error) == true && - json_get_string(request->data, "$.params.disc", 1, NAME_LEN_MAX, &sds_buf2, vcb_isdigit, &parse_error) == true && + json_get_string(request->data, "$.params.tag", 1, NAME_LEN_MAX, &sds_buf2, vcb_ismpdtag, &parse_error) == true && + json_get_string(request->data, "$.params.value", 1, NAME_LEN_MAX, &sds_buf3, vcb_isname, &parse_error) == true && json_get_uint(request->data, "$.params.to", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf1, &parse_error) == true && json_get_uint(request->data, "$.params.whence", 0, 2, &uint_buf2, &parse_error) == true && json_get_bool(request->data, "$.params.play", &bool_buf1, &parse_error) == true) { - rc = mympd_api_queue_insert_album_disc(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, uint_buf1, uint_buf2, &error) && + enum mpd_tag_type tag = mpd_tag_name_iparse(sds_buf2); + rc = mympd_api_queue_insert_album_tag(partition_state, &mympd_state->album_cache, sds_buf1, tag, sds_buf3, uint_buf1, uint_buf2, &error) && mpd_client_queue_check_start_play(partition_state, bool_buf1, &error); response->data = jsonrpc_respond_with_message_or_error(response->data, request->cmd_id, request->id, rc, JSONRPC_FACILITY_QUEUE, "Queue updated", error); @@ -1238,7 +1242,7 @@ void mympd_api_handler(struct t_mympd_state *mympd_state, struct t_partition_sta json_get_int(request->data, "$.params.end", -1, MPD_PLAYLIST_LENGTH_MAX, &int_buf1, &parse_error) == true && json_get_bool(request->data, "$.params.play", &bool_buf1, &parse_error) == true) { - rc = (request->cmd_id == MYMPD_API_QUEUE_APPEND_ALBUM_DISC + rc = (request->cmd_id == MYMPD_API_QUEUE_APPEND_ALBUM_RANGE ? mympd_api_queue_append_album_range(partition_state, &mympd_state->album_cache, sds_buf1, uint_buf1, int_buf1, &error) : mympd_api_queue_replace_album_range(partition_state, &mympd_state->album_cache, sds_buf1, uint_buf1, int_buf1, &error)) && mpd_client_queue_check_start_play(partition_state, bool_buf1, &error); @@ -1473,26 +1477,30 @@ void mympd_api_handler(struct t_mympd_state *mympd_state, struct t_partition_sta list_clear(&albumids); break; } - case MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_DISC: - case MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_DISC: + case MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_TAG: + case MYMPD_API_PLAYLIST_CONTENT_REPLACE_ALBUM_TAG: if (json_get_string(request->data, "$.params.plist", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &parse_error) == true && json_get_string(request->data, "$.params.albumid", 1, FILENAME_LEN_MAX, &sds_buf2, vcb_isalnum, &parse_error) == true && - json_get_string(request->data, "$.params.disc", 1, FILENAME_LEN_MAX, &sds_buf3, vcb_isdigit, &parse_error) == true) + json_get_string(request->data, "$.params.tag", 1, NAME_LEN_MAX, &sds_buf3, vcb_ismpdtag, &parse_error) == true && + json_get_string(request->data, "$.params.value", 1, NAME_LEN_MAX, &sds_buf4, vcb_isname, &parse_error) == true) { - rc = request->cmd_id == MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_DISC - ? mympd_api_playlist_content_append_album_disc(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, sds_buf3, &error) - : mympd_api_playlist_content_replace_album_disc(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, sds_buf3, &error); + enum mpd_tag_type tag = mpd_tag_name_iparse(sds_buf3); + rc = request->cmd_id == MYMPD_API_PLAYLIST_CONTENT_APPEND_ALBUM_TAG + ? mympd_api_playlist_content_append_album_tag(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, tag, sds_buf4, &error) + : mympd_api_playlist_content_replace_album_tag(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, tag, sds_buf4, &error); response->data = jsonrpc_respond_with_message_or_error(response->data, request->cmd_id, request->id, rc, JSONRPC_FACILITY_PLAYLIST, "Playlist updated", error); } break; - case MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_DISC: + case MYMPD_API_PLAYLIST_CONTENT_INSERT_ALBUM_TAG: if (json_get_string(request->data, "$.params.plist", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &parse_error) == true && json_get_string(request->data, "$.params.albumid", 1, FILENAME_LEN_MAX, &sds_buf2, vcb_isalnum, &parse_error) == true && - json_get_string(request->data, "$.params.disc", 1, FILENAME_LEN_MAX, &sds_buf3, vcb_isdigit, &parse_error) == true && + json_get_string(request->data, "$.params.tag", 1, NAME_LEN_MAX, &sds_buf3, vcb_ismpdtag, &parse_error) == true && + json_get_string(request->data, "$.params.value", 1, NAME_LEN_MAX, &sds_buf4, vcb_isname, &parse_error) == true && json_get_uint(request->data, "$.params.to", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf1, &parse_error) == true) { - rc = mympd_api_playlist_content_insert_album_disc(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, sds_buf3, uint_buf1, &error); + enum mpd_tag_type tag = mpd_tag_name_iparse(sds_buf3); + rc = mympd_api_playlist_content_insert_album_tag(partition_state, &mympd_state->album_cache, sds_buf1, sds_buf2, tag, sds_buf4, uint_buf1, &error); response->data = jsonrpc_respond_with_message_or_error(response->data, request->cmd_id, request->id, rc, JSONRPC_FACILITY_PLAYLIST, "Playlist updated", error); } diff --git a/src/mympd_api/playlists.c b/src/mympd_api/playlists.c index 29b44db34..57d25df5e 100644 --- a/src/mympd_api/playlists.c +++ b/src/mympd_api/playlists.c @@ -406,17 +406,20 @@ bool mympd_api_playlist_content_replace_albums(struct t_partition_state *partiti } /** - * Insert one disc of an album into a playlist + * Insert songs of an album filtered by tag into a playlist * @param partition_state pointer to partition state * @param album_cache pointer to album cache * @param plist stored playlist name * @param albumid album id to insert - * @param disc disc to insert + * @param tag MPD tag + * @param value MPD tag value * @param to position to insert * @param error pointer to an already allocated sds string for the error message * @return true on success, else false */ -bool mympd_api_playlist_content_insert_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, sds plist, sds albumid, sds disc, unsigned to, sds *error) { +bool mympd_api_playlist_content_insert_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds plist, sds albumid, enum mpd_tag_type tag, sds value, unsigned to, sds *error) +{ if (to != UINT_MAX && partition_state->mpd_state->feat.whence == false) { @@ -428,8 +431,8 @@ bool mympd_api_playlist_content_insert_album_disc(struct t_partition_state *part *error = sdscat(*error, "Album not found"); return false; } - sds expression = get_search_expression_album_disc(sdsempty(), partition_state->mpd_state->tag_albumartist, mpd_album, - disc, &partition_state->config->albums); + sds expression = get_search_expression_album_tag(sdsempty(), partition_state->mpd_state->tag_albumartist, mpd_album, + tag, value, &partition_state->config->albums); const char *sort = NULL; bool sortdesc = false; bool rc = mpd_client_search_add_to_plist(partition_state, expression, plist, to, sort, sortdesc, error); @@ -438,36 +441,38 @@ bool mympd_api_playlist_content_insert_album_disc(struct t_partition_state *part } /** - * Appends one disc of an album to a playlist + * Appends songs of an album filted by tag to a playlist * @param partition_state pointer to partition state * @param album_cache pointer to album cache * @param plist stored playlist name * @param albumid album id to append - * @param disc disc to append + * @param tag MPD tag + * @param value MPD tag value * @param error pointer to an already allocated sds string for the error message * @return true on success, else false */ -bool mympd_api_playlist_content_append_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds plist, sds albumid, sds disc, sds *error) +bool mympd_api_playlist_content_append_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds plist, sds albumid, enum mpd_tag_type tag, sds value, sds *error) { - return mympd_api_playlist_content_insert_album_disc(partition_state, album_cache, plist, albumid, disc, UINT_MAX, error); + return mympd_api_playlist_content_insert_album_tag(partition_state, album_cache, plist, albumid, tag, value, UINT_MAX, error); } /** - * Replaces the playlist with on disc of an album + * Replaces the playlist with songs of an album filtered by tag * @param partition_state pointer to partition state * @param album_cache pointer to album cache * @param plist stored playlist name * @param albumid album id to insert - * @param disc disc to insert + * @param tag MPD tag + * @param value MPD tag value * @param error pointer to an already allocated sds string for the error message * @return true on success, else false */ -bool mympd_api_playlist_content_replace_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds plist, sds albumid, sds disc, sds *error) +bool mympd_api_playlist_content_replace_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds plist, sds albumid, enum mpd_tag_type tag, sds value, sds *error) { return mpd_client_playlist_clear(partition_state, plist, error) && - mympd_api_playlist_content_append_album_disc(partition_state, album_cache, plist, albumid, disc, error); + mympd_api_playlist_content_append_album_tag(partition_state, album_cache, plist, albumid, tag, value, error); } /** diff --git a/src/mympd_api/playlists.h b/src/mympd_api/playlists.h index a5118da12..34c62d1ad 100644 --- a/src/mympd_api/playlists.h +++ b/src/mympd_api/playlists.h @@ -59,12 +59,12 @@ bool mympd_api_playlist_content_insert_albums(struct t_partition_state *partitio sds plist, struct t_list *albumids, unsigned to, sds *error); bool mympd_api_playlist_content_replace_albums(struct t_partition_state *partition_state, struct t_cache *album_cache, sds plist, struct t_list *albumids, sds *error); -bool mympd_api_playlist_content_append_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds plist, sds albumid, sds disc, sds *error); -bool mympd_api_playlist_content_insert_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds plist, sds albumid, sds disc, unsigned to, sds *error); -bool mympd_api_playlist_content_replace_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds plist, sds albumid, sds disc, sds *error); +bool mympd_api_playlist_content_append_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds plist, sds albumid, enum mpd_tag_type tag, sds value, sds *error); +bool mympd_api_playlist_content_insert_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds plist, sds albumid, enum mpd_tag_type tag, sds value, unsigned to, sds *error); +bool mympd_api_playlist_content_replace_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds plist, sds albumid, enum mpd_tag_type tag, sds value, sds *error); bool mympd_api_playlist_content_insert_search(struct t_partition_state *partition_state, sds expression, sds plist, unsigned to, const char *sort, bool sort_desc, sds *error); bool mympd_api_playlist_content_append_search(struct t_partition_state *partition_state, sds expression, sds plist, diff --git a/src/mympd_api/queue.c b/src/mympd_api/queue.c index 68dd9f720..3b82d2ca7 100644 --- a/src/mympd_api/queue.c +++ b/src/mympd_api/queue.c @@ -471,18 +471,19 @@ bool mympd_api_queue_replace_albums(struct t_partition_state *partition_state, s } /** - * Inserts one disc of an album into the queue + * Inserts songs of an album filtered by tag into the queue * @param partition_state pointer to partition state * @param album_cache pointer to album cache * @param albumid album id to insert - * @param disc disc to insert + * @param tag MPD tag + * @param value MPD tag value * @param to position to insert * @param whence how to interpret the to parameter * @param error pointer to an already allocated sds string for the error message * @return true on success, else false */ -bool mympd_api_queue_insert_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds albumid, sds disc, unsigned to, unsigned whence, sds *error) +bool mympd_api_queue_insert_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds albumid, enum mpd_tag_type tag, sds value, unsigned to, unsigned whence, sds *error) { if (whence != MPD_POSITION_ABSOLUTE && partition_state->mpd_state->feat.whence == false) @@ -495,8 +496,8 @@ bool mympd_api_queue_insert_album_disc(struct t_partition_state *partition_state *error = sdscat(*error, "Album not found"); return false; } - sds expression = get_search_expression_album_disc(sdsempty(), partition_state->mpd_state->tag_albumartist, - mpd_album, disc, &partition_state->config->albums); + sds expression = get_search_expression_album_tag(sdsempty(), partition_state->mpd_state->tag_albumartist, + mpd_album, tag, value, &partition_state->config->albums); const char *sort = NULL; bool sortdesc = false; bool rc = mpd_client_search_add_to_queue(partition_state, expression, to, whence, sort, sortdesc, error); @@ -505,34 +506,36 @@ bool mympd_api_queue_insert_album_disc(struct t_partition_state *partition_state } /** - * Appends one disc of an album to the queue + * Appends songs of an album filtered by tag to the queue * @param partition_state pointer to partition state * @param album_cache pointer to album cache * @param albumid album id to append - * @param disc disc to append + * @param tag MPD tag + * @param value MPD tag value * @param error pointer to an already allocated sds string for the error message * @return true on success, else false */ -bool mympd_api_queue_append_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds albumid, sds disc, sds *error) +bool mympd_api_queue_append_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds albumid, enum mpd_tag_type tag, sds value, sds *error) { - return mympd_api_queue_insert_album_disc(partition_state, album_cache, albumid, disc, UINT_MAX, MPD_POSITION_ABSOLUTE, error); + return mympd_api_queue_insert_album_tag(partition_state, album_cache, albumid, tag, value, UINT_MAX, MPD_POSITION_ABSOLUTE, error); } /** - * Replaces the queue with one disc of an album + * Replaces the queue with an album filted by tag * @param partition_state pointer to partition state * @param album_cache pointer to album cache * @param albumid album id to insert - * @param disc disc to insert + * @param tag MPD tag + * @param value MPD tag value * @param error pointer to an already allocated sds string for the error message * @return true on success, else false */ -bool mympd_api_queue_replace_album_disc(struct t_partition_state *partition_state,struct t_cache *album_cache, - sds albumid, sds disc, sds *error) +bool mympd_api_queue_replace_album_tag(struct t_partition_state *partition_state,struct t_cache *album_cache, + sds albumid, enum mpd_tag_type tag, sds value, sds *error) { return mpd_client_queue_clear(partition_state, error) && - mympd_api_queue_append_album_disc(partition_state, album_cache, albumid, disc, error); + mympd_api_queue_append_album_tag(partition_state, album_cache, albumid, tag, value, error); } /** diff --git a/src/mympd_api/queue.h b/src/mympd_api/queue.h index 144676408..4383ca57f 100644 --- a/src/mympd_api/queue.h +++ b/src/mympd_api/queue.h @@ -60,12 +60,12 @@ bool mympd_api_queue_insert_albums(struct t_partition_state *partition_state, st struct t_list *albumids, unsigned to, unsigned whence, sds *error); bool mympd_api_queue_replace_albums(struct t_partition_state *partition_state, struct t_cache *album_cache, struct t_list *albumids, sds *error); -bool mympd_api_queue_append_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds albumid, sds disc, sds *error); -bool mympd_api_queue_insert_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds albumid, sds disc, unsigned to, unsigned whence, sds *error); -bool mympd_api_queue_replace_album_disc(struct t_partition_state *partition_state, struct t_cache *album_cache, - sds albumid, sds disc, sds *error); +bool mympd_api_queue_append_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds albumid, enum mpd_tag_type tag, sds tag_value, sds *error); +bool mympd_api_queue_insert_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds albumid, enum mpd_tag_type tag, sds tag_value, unsigned to, unsigned whence, sds *error); +bool mympd_api_queue_replace_album_tag(struct t_partition_state *partition_state, struct t_cache *album_cache, + sds albumid, enum mpd_tag_type tag, sds tag_value, sds *error); bool mympd_api_queue_insert_album_range(struct t_partition_state *partition_state, struct t_cache *album_cache, sds albumid, unsigned start, int end, unsigned to, unsigned whence, sds *error); bool mympd_api_queue_append_album_range(struct t_partition_state *partition_state, struct t_cache *album_cache, diff --git a/src/mympd_api/settings.c b/src/mympd_api/settings.c index 5fdd4749e..4bd6009c6 100644 --- a/src/mympd_api/settings.c +++ b/src/mympd_api/settings.c @@ -516,18 +516,6 @@ bool mympd_api_settings_set(const char *path, sds key, sds value, int vtype, val return false; } } - else if (strcmp(key, "showWorkTagAlbumDetail") == 0) { - if (vtype == MJSON_TOK_TRUE) { - mympd_state->show_work_tag_album_detail = true; - } - else if (vtype == MJSON_TOK_FALSE) { - mympd_state->show_work_tag_album_detail = false; - } - else { - set_invalid_value(error, path, key, value, "Must be a boolean value"); - return false; - } - } else { set_invalid_field(error, path, key); return false; @@ -906,7 +894,6 @@ void mympd_api_settings_statefiles_global_read(struct t_mympd_state *mympd_state mympd_state->lyrics.vorbis_sylt = state_file_rw_string_sds(workdir, DIR_WORK_STATE, "lyrics_vorbis_sylt", mympd_state->lyrics.vorbis_sylt, vcb_isalnum, true); mympd_state->navbar_icons = state_file_rw_string_sds(workdir, DIR_WORK_STATE, "navbar_icons", mympd_state->navbar_icons, validate_json_array, true); mympd_state->tag_disc_empty_is_first = state_file_rw_bool(workdir, DIR_WORK_STATE, "tag_disc_empty_is_first", mympd_state->tag_disc_empty_is_first, true); - mympd_state->show_work_tag_album_detail = state_file_rw_bool(workdir, DIR_WORK_STATE, "show_work_tag_album_detail", mympd_state->show_work_tag_album_detail, true); strip_slash(mympd_state->music_directory); strip_slash(mympd_state->playlist_directory); @@ -1007,7 +994,6 @@ sds mympd_api_settings_get(struct t_mympd_state *mympd_state, struct t_partition buffer = tojson_raw(buffer, "viewBrowseRadioFavorites", mympd_state->view_browse_radio_favorites, true); buffer = tojson_raw(buffer, "navbarIcons", mympd_state->navbar_icons, true); buffer = tojson_bool(buffer, "tagDiscEmptyIsFirst", mympd_state->tag_disc_empty_is_first, true); - buffer = tojson_bool(buffer, "showWorkTagAlbumDetail", mympd_state->show_work_tag_album_detail, true); buffer = tojson_char(buffer, "albumMode", lookup_album_mode(mympd_state->config->albums.mode), true); buffer = tojson_char(buffer, "albumGroupTag", mpd_tag_name(mympd_state->config->albums.group_tag), true); buffer = tojson_raw(buffer, "webuiSettings", mympd_state->webui_settings, true);