diff --git a/src/js/contextmenu.js b/src/js/contextmenu.js index 8d780e9..d0c1612 100644 --- a/src/js/contextmenu.js +++ b/src/js/contextmenu.js @@ -212,6 +212,21 @@ function getSortMenuItems() { }; } +// get rating menu items +function getRatingMenuItems(selectedIndices) { + const items = {}; + for (let rating = 0; rating <= 5; rating++) { + const label = "★".repeat(rating) + "☆".repeat(5 - rating); + items[label] = async () => { + await Promise.all( + selectedIndices.map((i) => setSongRating(state.queue[i], rating)), + ); + updateQueueDisplay(); + }; + } + return items; +} + // show queue context menu function showQueueContextMenu(x, y, selectedIndices) { showContextMenu(x, y, { @@ -245,6 +260,10 @@ function showQueueContextMenu(x, y, selectedIndices) { ); updateQueueDisplay(); }, + [STRINGS.CONTEXT_RATING]: () => { + showContextMenu(x, y, getRatingMenuItems(selectedIndices)); + return false; // prevent cleanup, keep submenu open + }, [STRINGS.CONTEXT_MOVE_UP]: () => { const firstIdx = Math.min(...selectedIndices); if (firstIdx > 0) { diff --git a/src/js/player.js b/src/js/player.js index 1048e72..6666c22 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -109,14 +109,16 @@ const setFavoriteSong = async (song, force) => { } }; -// set song rating (1-5) +// set song rating (0-5) const setSongRating = async (song, rating) => { if (!song || !state.api || !state.settings.enableRatings) return; if (rating < 0 || rating > 5) return; + + await state.api.setRating(song.id, rating); + if (rating === 0) { state.ratings.delete(song.id); } else { - await state.api.setRating(song.id, rating); state.ratings.set(song.id, rating); } }; diff --git a/src/js/strings/en.js b/src/js/strings/en.js index c9df18d..4d8be3d 100644 --- a/src/js/strings/en.js +++ b/src/js/strings/en.js @@ -15,6 +15,7 @@ const STRINGS = { CONTEXT_MOVE_UP: "move up", CONTEXT_PLAY_NEXT: "play next", CONTEXT_PLAY: "play", + CONTEXT_RATING: "rating", CONTEXT_SORT: "sort", CONTEXT_UNFAVORITE: "unfavorite", // context menu - sort