mirror of
https://github.com/navidrome/navidrome.git
synced 2026-01-03 06:15:22 +00:00
fix(ui): replaygain for Artist Radio and Top Songs (#4328)
* Map replaygain info from getSimilarSongs2 * refactor: rename mapping function Signed-off-by: Deluan <deluan@navidrome.org> * refactor: Applied code review improvements Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
d041cb3249
commit
65961cce4b
@ -49,11 +49,21 @@ describe('ArtistActions', () => {
|
||||
// Mock console.error to suppress error logging in tests
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
|
||||
const songWithReplayGain = {
|
||||
id: 'rec1',
|
||||
replayGain: {
|
||||
albumGain: -5,
|
||||
albumPeak: 1,
|
||||
trackGain: -6,
|
||||
trackPeak: 0.8,
|
||||
},
|
||||
}
|
||||
|
||||
subsonic.getSimilarSongs2.mockResolvedValue({
|
||||
json: {
|
||||
'subsonic-response': {
|
||||
status: 'ok',
|
||||
similarSongs2: { song: [{ id: 'rec1' }] },
|
||||
similarSongs2: { song: [songWithReplayGain] },
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -61,7 +71,7 @@ describe('ArtistActions', () => {
|
||||
json: {
|
||||
'subsonic-response': {
|
||||
status: 'ok',
|
||||
topSongs: { song: [{ id: 'rec1' }] },
|
||||
topSongs: { song: [songWithReplayGain] },
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -93,6 +103,22 @@ describe('ArtistActions', () => {
|
||||
)
|
||||
expect(mockDispatch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('maps replaygain info', async () => {
|
||||
renderArtistActions()
|
||||
clickActionButton('radio')
|
||||
|
||||
await waitFor(() =>
|
||||
expect(subsonic.getSimilarSongs2).toHaveBeenCalledWith('ar1', 100),
|
||||
)
|
||||
const action = mockDispatch.mock.calls[0][0]
|
||||
expect(action.data.rec1).toMatchObject({
|
||||
rgAlbumGain: -5,
|
||||
rgAlbumPeak: 1,
|
||||
rgTrackGain: -6,
|
||||
rgTrackPeak: 0.8,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Play action', () => {
|
||||
@ -106,6 +132,22 @@ describe('ArtistActions', () => {
|
||||
expect(mockDispatch).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('maps replaygain info for top songs', async () => {
|
||||
renderArtistActions()
|
||||
clickActionButton('topSongs')
|
||||
|
||||
await waitFor(() =>
|
||||
expect(subsonic.getTopSongs).toHaveBeenCalledWith('Artist', 100),
|
||||
)
|
||||
const action = mockDispatch.mock.calls[0][0]
|
||||
expect(action.data.rec1).toMatchObject({
|
||||
rgAlbumGain: -5,
|
||||
rgAlbumPeak: 1,
|
||||
rgTrackGain: -6,
|
||||
rgTrackPeak: 0.8,
|
||||
})
|
||||
})
|
||||
|
||||
it('handles API rejection', async () => {
|
||||
subsonic.getTopSongs.mockRejectedValue(new Error('Network error'))
|
||||
|
||||
|
||||
@ -1,6 +1,32 @@
|
||||
import subsonic from '../subsonic/index.js'
|
||||
import { playTracks } from '../actions/index.js'
|
||||
|
||||
const mapReplayGain = (song) => {
|
||||
const { replayGain: rg } = song
|
||||
if (!rg) {
|
||||
return song
|
||||
}
|
||||
|
||||
return {
|
||||
...song,
|
||||
...(rg.albumGain !== undefined && { rgAlbumGain: rg.albumGain }),
|
||||
...(rg.albumPeak !== undefined && { rgAlbumPeak: rg.albumPeak }),
|
||||
...(rg.trackGain !== undefined && { rgTrackGain: rg.trackGain }),
|
||||
...(rg.trackPeak !== undefined && { rgTrackPeak: rg.trackPeak }),
|
||||
}
|
||||
}
|
||||
|
||||
const processSongsForPlayback = (songs) => {
|
||||
const songData = {}
|
||||
const ids = []
|
||||
songs.forEach((s) => {
|
||||
const song = mapReplayGain(s)
|
||||
songData[song.id] = song
|
||||
ids.push(song.id)
|
||||
})
|
||||
return { songData, ids }
|
||||
}
|
||||
|
||||
export const playTopSongs = async (dispatch, notify, artistName) => {
|
||||
const res = await subsonic.getTopSongs(artistName, 100)
|
||||
const data = res.json['subsonic-response']
|
||||
@ -17,12 +43,7 @@ export const playTopSongs = async (dispatch, notify, artistName) => {
|
||||
return
|
||||
}
|
||||
|
||||
const songData = {}
|
||||
const ids = []
|
||||
songs.forEach((s) => {
|
||||
songData[s.id] = s
|
||||
ids.push(s.id)
|
||||
})
|
||||
const { songData, ids } = processSongsForPlayback(songs)
|
||||
dispatch(playTracks(songData, ids))
|
||||
}
|
||||
|
||||
@ -42,12 +63,7 @@ export const playSimilar = async (dispatch, notify, id) => {
|
||||
return
|
||||
}
|
||||
|
||||
const songData = {}
|
||||
const ids = []
|
||||
songs.forEach((s) => {
|
||||
songData[s.id] = s
|
||||
ids.push(s.id)
|
||||
})
|
||||
const { songData, ids } = processSongsForPlayback(songs)
|
||||
dispatch(playTracks(songData, ids))
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user