feat(ui): add 'Show in Playlist' context menu (#4139)

* Update song playlist menu and endpoint

* feat(ui): show submenu on click, not on hover

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): integrate dataProvider for fetching playlists in song context menu

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): update song context menu to use dataProvider for fetching playlists and inspecting songs

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): stop event propagation when closing playlist submenu

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): add 'show in playlist' option to options object

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan Quintão 2025-05-30 21:26:35 -04:00 committed by GitHub
parent 6dd98e0bed
commit ded8cf236e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 249 additions and 8 deletions

View file

@ -59,6 +59,7 @@ func (n *Router) routes() http.Handler {
n.addPlaylistRoute(r)
n.addPlaylistTrackRoute(r)
n.addSongPlaylistsRoute(r)
n.addMissingFilesRoute(r)
n.addInspectRoute(r)
n.addConfigRoute(r)
@ -142,6 +143,15 @@ func (n *Router) addPlaylistTrackRoute(r chi.Router) {
})
}
func (n *Router) addSongPlaylistsRoute(r chi.Router) {
r.Route("/song/{id}", func(r chi.Router) {
r.Use(server.URLParamsMiddleware)
r.Get("/playlists", func(w http.ResponseWriter, r *http.Request) {
getSongPlaylists(n.ds)(w, r)
})
})
}
func (n *Router) addMissingFilesRoute(r chi.Router) {
r.Route("/missing", func(r chi.Router) {
n.RX(r, "/", newMissingRepository(n.ds), false)

View file

@ -207,3 +207,21 @@ func reorderItem(ds model.DataStore) http.HandlerFunc {
}
}
}
func getSongPlaylists(ds model.DataStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
p := req.Params(r)
trackId, _ := p.String(":id")
playlists, err := ds.Playlist(r.Context()).GetPlaylists(trackId)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
data, err := json.Marshal(playlists)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, _ = w.Write(data)
}
}