mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-04 21:17:37 +03:00
Trigger UI refresh on media annotation events: star
, setRating
and scrobble
This commit is contained in:
parent
2afb2db7ef
commit
cefc939909
8 changed files with 33 additions and 13 deletions
|
@ -47,7 +47,8 @@ func CreateSubsonicAPIRouter() *subsonic.Router {
|
||||||
players := core.NewPlayers(dataStore)
|
players := core.NewPlayers(dataStore)
|
||||||
externalMetadata := core.NewExternalMetadata(dataStore)
|
externalMetadata := core.NewExternalMetadata(dataStore)
|
||||||
scanner := GetScanner()
|
scanner := GetScanner()
|
||||||
router := subsonic.New(dataStore, artwork, mediaStreamer, archiver, players, externalMetadata, scanner)
|
broker := GetBroker()
|
||||||
|
router := subsonic.New(dataStore, artwork, mediaStreamer, archiver, players, externalMetadata, scanner, broker)
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ func createScheduler() scheduler.Scheduler {
|
||||||
|
|
||||||
// wire_injectors.go:
|
// wire_injectors.go:
|
||||||
|
|
||||||
var allProviders = wire.NewSet(core.Set, subsonic.New, app.New, persistence.New)
|
var allProviders = wire.NewSet(core.Set, subsonic.New, app.New, persistence.New, GetBroker)
|
||||||
|
|
||||||
// Scanner must be a Singleton
|
// Scanner must be a Singleton
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -21,6 +21,7 @@ var allProviders = wire.NewSet(
|
||||||
subsonic.New,
|
subsonic.New,
|
||||||
app.New,
|
app.New,
|
||||||
persistence.New,
|
persistence.New,
|
||||||
|
GetBroker,
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateServer(musicFolder string) *server.Server {
|
func CreateServer(musicFolder string) *server.Server {
|
||||||
|
@ -33,7 +34,6 @@ func CreateServer(musicFolder string) *server.Server {
|
||||||
func CreateAppRouter() *app.Router {
|
func CreateAppRouter() *app.Router {
|
||||||
panic(wire.Build(
|
panic(wire.Build(
|
||||||
allProviders,
|
allProviders,
|
||||||
GetBroker,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,6 @@ func GetScanner() scanner.Scanner {
|
||||||
func createScanner() scanner.Scanner {
|
func createScanner() scanner.Scanner {
|
||||||
panic(wire.Build(
|
panic(wire.Build(
|
||||||
allProviders,
|
allProviders,
|
||||||
GetBroker,
|
|
||||||
scanner.New,
|
scanner.New,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/navidrome/navidrome/log"
|
"github.com/navidrome/navidrome/log"
|
||||||
"github.com/navidrome/navidrome/model"
|
"github.com/navidrome/navidrome/model"
|
||||||
"github.com/navidrome/navidrome/scanner"
|
"github.com/navidrome/navidrome/scanner"
|
||||||
|
"github.com/navidrome/navidrome/server/events"
|
||||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||||
"github.com/navidrome/navidrome/utils"
|
"github.com/navidrome/navidrome/utils"
|
||||||
)
|
)
|
||||||
|
@ -30,12 +31,13 @@ type Router struct {
|
||||||
Players core.Players
|
Players core.Players
|
||||||
ExternalMetadata core.ExternalMetadata
|
ExternalMetadata core.ExternalMetadata
|
||||||
Scanner scanner.Scanner
|
Scanner scanner.Scanner
|
||||||
|
Broker events.Broker
|
||||||
|
|
||||||
mux http.Handler
|
mux http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ds model.DataStore, artwork core.Artwork, streamer core.MediaStreamer, archiver core.Archiver, players core.Players,
|
func New(ds model.DataStore, artwork core.Artwork, streamer core.MediaStreamer, archiver core.Archiver, players core.Players,
|
||||||
externalMetadata core.ExternalMetadata, scanner scanner.Scanner) *Router {
|
externalMetadata core.ExternalMetadata, scanner scanner.Scanner, broker events.Broker) *Router {
|
||||||
r := &Router{
|
r := &Router{
|
||||||
DataStore: ds,
|
DataStore: ds,
|
||||||
Artwork: artwork,
|
Artwork: artwork,
|
||||||
|
@ -44,6 +46,7 @@ func New(ds model.DataStore, artwork core.Artwork, streamer core.MediaStreamer,
|
||||||
Players: players,
|
Players: players,
|
||||||
ExternalMetadata: externalMetadata,
|
ExternalMetadata: externalMetadata,
|
||||||
Scanner: scanner,
|
Scanner: scanner,
|
||||||
|
Broker: broker,
|
||||||
}
|
}
|
||||||
r.mux = r.routes()
|
r.mux = r.routes()
|
||||||
return r
|
return r
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/navidrome/navidrome/log"
|
"github.com/navidrome/navidrome/log"
|
||||||
"github.com/navidrome/navidrome/model"
|
"github.com/navidrome/navidrome/model"
|
||||||
"github.com/navidrome/navidrome/model/request"
|
"github.com/navidrome/navidrome/model/request"
|
||||||
|
"github.com/navidrome/navidrome/server/events"
|
||||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||||
"github.com/navidrome/navidrome/utils"
|
"github.com/navidrome/navidrome/utils"
|
||||||
)
|
)
|
||||||
|
@ -17,10 +18,11 @@ import (
|
||||||
type MediaAnnotationController struct {
|
type MediaAnnotationController struct {
|
||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
npRepo core.NowPlaying
|
npRepo core.NowPlaying
|
||||||
|
broker events.Broker
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMediaAnnotationController(ds model.DataStore, npr core.NowPlaying) *MediaAnnotationController {
|
func NewMediaAnnotationController(ds model.DataStore, npr core.NowPlaying, broker events.Broker) *MediaAnnotationController {
|
||||||
return &MediaAnnotationController{ds: ds, npRepo: npr}
|
return &MediaAnnotationController{ds: ds, npRepo: npr, broker: broker}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MediaAnnotationController) SetRating(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
func (c *MediaAnnotationController) SetRating(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||||
|
@ -55,16 +57,22 @@ func (c *MediaAnnotationController) setRating(ctx context.Context, id string, ra
|
||||||
if exist, err = c.ds.Artist(ctx).Exists(id); err != nil {
|
if exist, err = c.ds.Artist(ctx).Exists(id); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if exist {
|
} else if exist {
|
||||||
return c.ds.Artist(ctx).SetRating(rating, id)
|
err = c.ds.Artist(ctx).SetRating(rating, id)
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{Resource: "artist"})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if exist, err = c.ds.Album(ctx).Exists(id); err != nil {
|
if exist, err = c.ds.Album(ctx).Exists(id); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if exist {
|
} else if exist {
|
||||||
return c.ds.Album(ctx).SetRating(rating, id)
|
err = c.ds.Album(ctx).SetRating(rating, id)
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{Resource: "album"})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.ds.MediaFile(ctx).SetRating(rating, id)
|
err = c.ds.MediaFile(ctx).SetRating(rating, id)
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{Resource: "song"})
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MediaAnnotationController) Star(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
func (c *MediaAnnotationController) Star(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||||
|
@ -166,6 +174,7 @@ func (c *MediaAnnotationController) scrobblerRegister(ctx context.Context, playe
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error while scrobbling", "trackId", trackId, "user", username, err)
|
log.Error("Error while scrobbling", "trackId", trackId, "user", username, err)
|
||||||
} else {
|
} else {
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{})
|
||||||
log.Info("Scrobbled", "title", mf.Title, "artist", mf.Artist, "user", username)
|
log.Info("Scrobbled", "title", mf.Title, "artist", mf.Artist, "user", username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +218,7 @@ func (c *MediaAnnotationController) setStar(ctx context.Context, star bool, ids
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{Resource: "album"})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
exist, err = tx.Artist(ctx).Exists(id)
|
exist, err = tx.Artist(ctx).Exists(id)
|
||||||
|
@ -220,12 +230,14 @@ func (c *MediaAnnotationController) setStar(ctx context.Context, star bool, ids
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{Resource: "artist"})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = tx.MediaFile(ctx).SetStar(star, ids...)
|
err = tx.MediaFile(ctx).SetStar(star, ids...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
c.broker.SendMessage(&events.RefreshResource{})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -34,7 +34,8 @@ func initAlbumListController(router *Router) *AlbumListController {
|
||||||
func initMediaAnnotationController(router *Router) *MediaAnnotationController {
|
func initMediaAnnotationController(router *Router) *MediaAnnotationController {
|
||||||
dataStore := router.DataStore
|
dataStore := router.DataStore
|
||||||
nowPlaying := core.NewNowPlayingRepository()
|
nowPlaying := core.NewNowPlayingRepository()
|
||||||
mediaAnnotationController := NewMediaAnnotationController(dataStore, nowPlaying)
|
broker := router.Broker
|
||||||
|
mediaAnnotationController := NewMediaAnnotationController(dataStore, nowPlaying, broker)
|
||||||
return mediaAnnotationController
|
return mediaAnnotationController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,5 +96,5 @@ var allProviders = wire.NewSet(
|
||||||
NewMediaRetrievalController,
|
NewMediaRetrievalController,
|
||||||
NewStreamController,
|
NewStreamController,
|
||||||
NewBookmarksController,
|
NewBookmarksController,
|
||||||
NewLibraryScanningController, core.NewNowPlayingRepository, wire.FieldsOf(new(*Router), "DataStore", "Artwork", "Streamer", "Archiver", "ExternalMetadata", "Scanner"),
|
NewLibraryScanningController, core.NewNowPlayingRepository, wire.FieldsOf(new(*Router), "DataStore", "Artwork", "Streamer", "Archiver", "ExternalMetadata", "Scanner", "Broker"),
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,7 +20,7 @@ var allProviders = wire.NewSet(
|
||||||
NewBookmarksController,
|
NewBookmarksController,
|
||||||
NewLibraryScanningController,
|
NewLibraryScanningController,
|
||||||
core.NewNowPlayingRepository,
|
core.NewNowPlayingRepository,
|
||||||
wire.FieldsOf(new(*Router), "DataStore", "Artwork", "Streamer", "Archiver", "ExternalMetadata", "Scanner"),
|
wire.FieldsOf(new(*Router), "DataStore", "Artwork", "Streamer", "Archiver", "ExternalMetadata", "Scanner", "Broker"),
|
||||||
)
|
)
|
||||||
|
|
||||||
func initSystemController(router *Router) *SystemController {
|
func initSystemController(router *Router) *SystemController {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
RatingField,
|
RatingField,
|
||||||
QualityInfo,
|
QualityInfo,
|
||||||
useSelectedFields,
|
useSelectedFields,
|
||||||
|
useResourceRefresh,
|
||||||
} from '../common'
|
} from '../common'
|
||||||
import { AddToPlaylistDialog } from '../dialogs'
|
import { AddToPlaylistDialog } from '../dialogs'
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
|
@ -88,6 +89,7 @@ const AlbumSongs = (props) => {
|
||||||
const classes = useStyles({ isDesktop })
|
const classes = useStyles({ isDesktop })
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const version = useVersion()
|
const version = useVersion()
|
||||||
|
useResourceRefresh('song', 'album')
|
||||||
|
|
||||||
const toggleableFields = useMemo(() => {
|
const toggleableFields = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import {
|
||||||
SongTitleField,
|
SongTitleField,
|
||||||
QualityInfo,
|
QualityInfo,
|
||||||
useSelectedFields,
|
useSelectedFields,
|
||||||
|
useResourceRefresh,
|
||||||
} from '../common'
|
} from '../common'
|
||||||
import { AddToPlaylistDialog } from '../dialogs'
|
import { AddToPlaylistDialog } from '../dialogs'
|
||||||
import { AlbumLinkField } from '../song/AlbumLinkField'
|
import { AlbumLinkField } from '../song/AlbumLinkField'
|
||||||
|
@ -91,6 +92,7 @@ const PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {
|
||||||
const refresh = useRefresh()
|
const refresh = useRefresh()
|
||||||
const notify = useNotify()
|
const notify = useNotify()
|
||||||
const version = useVersion()
|
const version = useVersion()
|
||||||
|
useResourceRefresh('song', 'playlist')
|
||||||
|
|
||||||
const onAddToPlaylist = useCallback(
|
const onAddToPlaylist = useCallback(
|
||||||
(pls) => {
|
(pls) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue