Skip to content

Commit

Permalink
Feat: Add API method MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS, replace…
Browse files Browse the repository at this point in the history
…s MYMPD_API_PLAYLIST_CONTENT_RM_SONG
  • Loading branch information
jcorporation committed May 21, 2023
1 parent fc0269c commit 0022823
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 61 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ https://github.com/jcorporation/myMPD/

## myMPD v10.4.0 (not yet released)

### API changes

- MYMPD_API_QUEUE_RM_SONG -> MYMPD_API_QUEUE_RM_IDS
- MYMPD_API_QUEUE_MOVE_SONG -> MYMPD_API_QUEUE_MOVE_POSITION
- MYMPD_API_PLAYLIST_CONTENT_RM_SONG -> MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS
- MYMPD_API_PLAYLIST_CONTENT_MOVE_SONG -> MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION

### Changelog

- Feat: migrate to JavaScript fetch() API #1006
Expand Down
45 changes: 23 additions & 22 deletions htdocs/js/BrowsePlaylists.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,33 +270,34 @@ function updateSmartPlaylists(force) {
}

/**
* Removes a song from a playlist
* @param {string} mode range = remove a range of songs,
* single = remove one song
* Removes positions from a playlist
* @param {string} plist the playlist
* @param {Array} positions Positions to remove
* @returns {void}
*/
//eslint-disable-next-line no-unused-vars
function removeFromPlaylistPositions(plist, positions) {
sendAPI("MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS", {
"plist": plist,
"positions": positions
}, null, false);
setUpdateViewId('BrowsePlaylistDetailList');
}

/**
* Removes a range from a playlist
* @param {string} plist the playlist
* @param {number} start Start of the range (including) / song pos
* @param {number} [end] End playlist position (excluding), use -1 for open end
* @returns {void}
*/
//eslint-disable-next-line no-unused-vars
function removeFromPlaylist(mode, plist, start, end) {
switch(mode) {
case 'range':
sendAPI("MYMPD_API_PLAYLIST_CONTENT_RM_RANGE", {
"plist": plist,
"start": start,
"end": end
}, null, false);
break;
case 'single':
sendAPI("MYMPD_API_PLAYLIST_CONTENT_RM_SONG", {
"plist": plist,
"pos": start
}, null, false);
break;
default:
return;
}
function removeFromPlaylistRange(plist, start, end) {
sendAPI("MYMPD_API_PLAYLIST_CONTENT_RM_RANGE", {
"plist": plist,
"start": start,
"end": end
}, null, false);
setUpdateViewId('BrowsePlaylistDetailList');
}

Expand Down Expand Up @@ -856,7 +857,7 @@ function showClearPlaylist() {
* @returns {void}
*/
function playlistMoveSong(from, to) {
sendAPI("MYMPD_API_PLAYLIST_CONTENT_MOVE_SONG", {
sendAPI("MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION", {
"plist": app.current.filter,
"from": from,
"to": to
Expand Down
31 changes: 21 additions & 10 deletions htdocs/js/QueueCurrent.js
Original file line number Diff line number Diff line change
Expand Up @@ -732,13 +732,13 @@ function setSongPos() {
newSongPos--;
}
if (plist === 'queue') {
sendAPI("MYMPD_API_QUEUE_MOVE_SONG", {
sendAPI("MYMPD_API_QUEUE_MOVE_POSITION", {
"from": oldSongPos,
"to": newSongPos
}, setSongPosCheckError, true);
}
else {
sendAPI("MYMPD_API_PLAYLIST_CONTENT_MOVE_SONG", {
sendAPI("MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION", {
"plist": plist,
"from": oldSongPos,
"to": newSongPos
Expand All @@ -748,7 +748,7 @@ function setSongPos() {
}

/**
* Handles the MYMPD_API_QUEUE_MOVE_SONG and jsonrpc response
* Handles the MYMPD_API_QUEUE_MOVE_POSITION and jsonrpc response
* @param {object} obj jsonrpc response
* @returns {void}
*/
Expand Down Expand Up @@ -826,7 +826,7 @@ function removeFromQueueRange(start, end) {
*/
//eslint-disable-next-line no-unused-vars
function removeFromQueueIDs(ids) {
sendAPI("MYMPD_API_QUEUE_RM_SONG_IDS", {
sendAPI("MYMPD_API_QUEUE_RM_IDS", {
"songIds": ids
}, null, false);
}
Expand Down Expand Up @@ -855,21 +855,32 @@ function gotoPlayingSong() {
}
}

/**
* Moves a entry in the queue
* @param {number} from from position
* @param {number} to to position
* @returns {void}
*/
function queueMovePosition(from, to) {
sendAPI("MYMPD_API_QUEUE_MOVE_POSITION", {
"from": from,
"to": to
}, null, false);
}

/**
* Plays the selected song after the current song.
* Uses the priority if in random mode else moves the song after current playing song.
* Uses the priority if MPS is in random mode, else moves the song after current playing song.
* @param {number} songId current playing song id (for priority mode)
* @param {number} songPos current playing song position (for move mode)
* @returns {void}
*/
//eslint-disable-next-line no-unused-vars
function playAfterCurrent(songId, songPos) {
if (settings.partition.random === false) {
//not in random mode - move song after current playling song
sendAPI("MYMPD_API_QUEUE_MOVE_SONG", {
"from": songPos,
"to": currentState.songPos !== undefined ? currentState.songPos + 1 : 0
}, null, false);
//not in random mode - move song after current playing song
const newSongPos = currentState.songPos !== undefined ? currentState.songPos + 1 : 0;
queueMovePosition(songPos, newSongPos);
}
else {
//in random mode - set song priority
Expand Down
19 changes: 12 additions & 7 deletions htdocs/js/apidoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ const APIparams = {
"example": 2,
"desc": "Position"
},
"positions": {
"type": APItypes.array,
"example": "[2,3]",
"desc": "Positions"
},
"play": {
"type": APItypes.bool,
"example": true,
Expand Down Expand Up @@ -355,8 +360,8 @@ const APImethods = {
"cols": APIparams.cols
}
},
"MYMPD_API_QUEUE_RM_SONG_IDS": {
"desc": "Removes songs from the queue.",
"MYMPD_API_QUEUE_RM_IDS": {
"desc": "Removes defined entries from the queue.",
"params": {
"songIds": APIparams.songIds
}
Expand All @@ -376,7 +381,7 @@ const APImethods = {
}
}
},
"MYMPD_API_QUEUE_MOVE_SONG": {
"MYMPD_API_QUEUE_MOVE_POSITION": {
"desc": "Moves a song in the queue.",
"params": {
"from": APIparams.from,
Expand Down Expand Up @@ -514,7 +519,7 @@ const APImethods = {
}
}
},
"MYMPD_API_PLAYLIST_CONTENT_MOVE_SONG": {
"MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION": {
"desc": "Moves a song in the playlist.",
"params": {
"plist": APIparams.plist,
Expand Down Expand Up @@ -566,11 +571,11 @@ const APImethods = {
"expression": APIparams.expression
}
},
"MYMPD_API_PLAYLIST_CONTENT_RM_SONG": {
"desc": "Removes a song from the playlist.",
"MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS": {
"desc": "Removes entries from the playlist. Positions must be sorted descending.",
"params": {
"plist": APIparams.plist,
"pos": APIparams.pos
"positions": APIparams.positions
}
},
"MYMPD_API_PLAYLIST_CONTENT_RM_RANGE": {
Expand Down
2 changes: 1 addition & 1 deletion htdocs/js/clickActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function clickQuickRemove(target) {
case 'BrowsePlaylistsDetail': {
const pos = getData(target.parentNode.parentNode, 'songpos');
const plist = getDataId('BrowsePlaylistsDetailList', 'uri');
removeFromPlaylist('single', plist, pos);
removeFromPlaylistPositions(plist, [pos]);
break;
}
case 'QueueJukebox': {
Expand Down
6 changes: 3 additions & 3 deletions htdocs/js/contextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,13 +542,13 @@ function createMenuLists(target, contextMenuTitle, contextMenuBody) {
const songpos = getData(dataNode, 'songpos');
const playlistLength = getData(table, 'playlistlength');
addMenuItem(contextMenuBody, {"cmd": "showSetSongPos", "options": [plist, songpos]}, 'Move song');
addMenuItem(contextMenuBody, {"cmd": "removeFromPlaylist", "options": ["single", plist, songpos]}, 'Remove');
addMenuItem(contextMenuBody, {"cmd": "removeFromPlaylistPositions", "options": [plist, [songpos]]}, 'Remove');
if (features.featPlaylistRmRange === true) {
if (songpos > 0) {
addMenuItem(contextMenuBody, {"cmd": "removeFromPlaylist", "options": ["range", plist, 0, songpos]}, 'Remove all upwards');
addMenuItem(contextMenuBody, {"cmd": "removeFromPlaylistRange", "options": [plist, 0, songpos]}, 'Remove all upwards');
}
if (songpos + 1 < playlistLength) {
addMenuItem(contextMenuBody, {"cmd": "removeFromPlaylist", "options": ["range", plist, songpos + 1, -1]}, 'Remove all downwards');
addMenuItem(contextMenuBody, {"cmd": "removeFromPlaylistRange", "options": [plist, songpos + 1, -1]}, 'Remove all downwards');
}
}
}
Expand Down
15 changes: 7 additions & 8 deletions htdocs/js/tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,13 @@ function dragAndDropTable(tableId) {
tr[i].classList.remove('dragover');
}
document.getElementById(tableId).classList.add('opacity05');
if (app.id === 'QueueCurrent') {
sendAPI("MYMPD_API_QUEUE_MOVE_SONG", {
"from": oldSongPos,
"to": newSongPos
}, null, false);
}
else if (app.id === 'BrowsePlaylistsDetail') {
playlistMoveSong(oldSongPos, newSongPos);
switch(app.id) {
case 'QueueCurrent':
queueMovePosition(oldSongPos, newSongPos);
break;
case 'BrowsePlaylistsDetail':
playlistMoveSong(oldSongPos, newSongPos);
break;
}
}, false);
}
Expand Down
8 changes: 4 additions & 4 deletions src/lib/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@
X(MYMPD_API_PLAYLIST_CONTENT_INSERT_SEARCH) \
X(MYMPD_API_PLAYLIST_CONTENT_INSERT_URI) \
X(MYMPD_API_PLAYLIST_CONTENT_LIST) \
X(MYMPD_API_PLAYLIST_CONTENT_MOVE_SONG) \
X(MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION) \
X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_SEARCH) \
X(MYMPD_API_PLAYLIST_CONTENT_REPLACE_URI) \
X(MYMPD_API_PLAYLIST_CONTENT_RM_RANGE) \
X(MYMPD_API_PLAYLIST_CONTENT_SHUFFLE) \
X(MYMPD_API_PLAYLIST_CONTENT_SORT) \
X(MYMPD_API_PLAYLIST_CONTENT_RM_SONG) \
X(MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS) \
X(MYMPD_API_PLAYLIST_LIST) \
X(MYMPD_API_PLAYLIST_RENAME) \
X(MYMPD_API_PLAYLIST_RM) \
Expand All @@ -123,14 +123,14 @@
X(MYMPD_API_QUEUE_INSERT_SEARCH) \
X(MYMPD_API_QUEUE_INSERT_URI) \
X(MYMPD_API_QUEUE_LIST) \
X(MYMPD_API_QUEUE_MOVE_SONG) \
X(MYMPD_API_QUEUE_MOVE_POSITION) \
X(MYMPD_API_QUEUE_PRIO_SET) \
X(MYMPD_API_QUEUE_PRIO_SET_HIGHEST) \
X(MYMPD_API_QUEUE_REPLACE_PLAYLIST) \
X(MYMPD_API_QUEUE_REPLACE_SEARCH) \
X(MYMPD_API_QUEUE_REPLACE_URI) \
X(MYMPD_API_QUEUE_RM_RANGE) \
X(MYMPD_API_QUEUE_RM_SONG_IDS) \
X(MYMPD_API_QUEUE_RM_IDS) \
X(MYMPD_API_QUEUE_SAVE) \
X(MYMPD_API_QUEUE_SEARCH) \
X(MYMPD_API_QUEUE_SEARCH_ADV) \
Expand Down
16 changes: 10 additions & 6 deletions src/mympd_api/mympd_api_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ void mympd_api_handler(struct t_partition_state *partition_state, struct t_work_
case MYMPD_API_QUEUE_CROP_OR_CLEAR:
response->data = mympd_api_queue_crop(partition_state, response->data, request->cmd_id, request->id, true);
break;
case MYMPD_API_QUEUE_RM_SONG_IDS: {
case MYMPD_API_QUEUE_RM_IDS: {
struct t_list song_ids;
list_init(&song_ids);
if (json_get_array_llong(request->data, "$.params.songIds", &song_ids, MPD_PLAYLIST_LENGTH_MAX, &error) == true) {
Expand All @@ -898,7 +898,7 @@ void mympd_api_handler(struct t_partition_state *partition_state, struct t_work_
response->data = mympd_respond_with_error_or_ok(partition_state, response->data, request->cmd_id, request->id, rc, "mpd_run_delete_range", &result);
}
break;
case MYMPD_API_QUEUE_MOVE_SONG:
case MYMPD_API_QUEUE_MOVE_POSITION:
if (json_get_uint(request->data, "$.params.from", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf1, &error) == true &&
json_get_uint(request->data, "$.params.to", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf2, &error) == true)
{
Expand Down Expand Up @@ -1167,7 +1167,7 @@ void mympd_api_handler(struct t_partition_state *partition_state, struct t_work_
}
}
break;
case MYMPD_API_PLAYLIST_CONTENT_MOVE_SONG:
case MYMPD_API_PLAYLIST_CONTENT_MOVE_POSITION:
if (json_get_string(request->data, "$.params.plist", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &error) == true &&
json_get_uint(request->data, "$.params.from", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf1, &error) == true &&
json_get_uint(request->data, "$.params.to", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf2, &error) == true)
Expand All @@ -1179,14 +1179,18 @@ void mympd_api_handler(struct t_partition_state *partition_state, struct t_work_
response->data = mympd_respond_with_error_or_ok(partition_state, response->data, request->cmd_id, request->id, rc, "mpd_run_playlist_move", &result);
}
break;
case MYMPD_API_PLAYLIST_CONTENT_RM_SONG:
case MYMPD_API_PLAYLIST_CONTENT_RM_POSITIONS: {
struct t_list positions;
list_init(&positions);
if (json_get_string(request->data, "$.params.plist", 1, FILENAME_LEN_MAX, &sds_buf1, vcb_isfilename, &error) == true &&
json_get_uint(request->data, "$.params.pos", 0, MPD_PLAYLIST_LENGTH_MAX, &uint_buf1, &error) == true)
json_get_array_llong(request->data, "$.params.positions", &positions, MPD_PLAYLIST_LENGTH_MAX, &error) == true)
{
rc = mpd_run_playlist_delete(partition_state->conn, sds_buf1, uint_buf1);
rc = mympd_api_playlist_content_rm_positions(partition_state, sds_buf1, &positions);
response->data = mympd_respond_with_error_or_ok(partition_state, response->data, request->cmd_id, request->id, rc, "mpd_run_playlist_delete", &result);
}
list_clear(&positions);
break;
}
case MYMPD_API_PLAYLIST_CONTENT_RM_RANGE:
if (mympd_state->mpd_state->feat_playlist_rm_range == false) {
response->data = jsonrpc_respond_message(response->data, request->cmd_id, request->id,
Expand Down
25 changes: 25 additions & 0 deletions src/mympd_api/playlists.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,31 @@ static void free_t_pl_data(void *data) {
FREE_PTR(pl_data);
}

/**
* Removes entries defined by positions from the stored playlist
* Positions must be sorted descending.
* @param partition_state pointer to partition state
* @param plist stored playlist name
* @param positions list of positions to remove
* @return true on success, else false
*/
bool mympd_api_playlist_content_rm_positions(struct t_partition_state *partition_state, sds plist, struct t_list *positions) {
if (mpd_command_list_begin(partition_state->conn, false) == true) {
struct t_list_node *current = positions->head;
while (current != NULL) {
bool rc = mpd_send_playlist_delete(partition_state->conn, plist, (unsigned)current->value_i);
if (rc == false) {
MYMPD_LOG_ERROR("Error adding command to command list mpd_send_playlist_delete");
break;
}
current = current->next;
}
return mpd_command_list_end(partition_state->conn) &&
mpd_response_finish(partition_state->conn);
}
return false;
}

/**
* Lists mpd playlists and myMPD smart playlists
* @param partition_state pointer to partition state
Expand Down
1 change: 1 addition & 0 deletions src/mympd_api/playlists.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ sds mympd_api_playlist_rename(struct t_partition_state *partition_state, sds buf
long request_id, const char *old_playlist, const char *new_playlist);
sds mympd_api_playlist_delete_all(struct t_partition_state *partition_state, sds buffer,
long request_id, enum plist_delete_criterias criteria);
bool mympd_api_playlist_content_rm_positions(struct t_partition_state *partition_state, sds plist, struct t_list *positions);
#endif

0 comments on commit 0022823

Please sign in to comment.