feat(ui): add Now Playing panel for admins (#4209)
* feat(ui): add Now Playing panel and integrate now playing count updates Signed-off-by: Deluan <deluan@navidrome.org> * fix: check return value in test to satisfy linter * fix: format React code with prettier * fix: resolve race condition in play tracker test * fix: log error when fetching now playing data fails Signed-off-by: Deluan <deluan@navidrome.org> * feat(ui): refactor Now Playing panel with new components and error handling Signed-off-by: Deluan <deluan@navidrome.org> * fix(ui): adjust padding and height in Now Playing panel for improved layout Signed-off-by: Deluan <deluan@navidrome.org> * fix(cache): add automatic cleanup to prevent goroutine leak on cache garbage collection Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
@@ -54,6 +54,16 @@ const startScan = (options) => httpClient(url('startScan', null, options))
|
||||
|
||||
const getScanStatus = () => httpClient(url('getScanStatus'))
|
||||
|
||||
const getNowPlaying = () => httpClient(url('getNowPlaying'))
|
||||
|
||||
const getAvatarUrl = (username, size) =>
|
||||
baseUrl(
|
||||
url('getAvatar', null, {
|
||||
username,
|
||||
...(size && { size }),
|
||||
}),
|
||||
)
|
||||
|
||||
const getCoverArtUrl = (record, size, square) => {
|
||||
const options = {
|
||||
...(record.updatedAt && { _: record.updatedAt }),
|
||||
@@ -110,7 +120,9 @@ export default {
|
||||
setRating,
|
||||
startScan,
|
||||
getScanStatus,
|
||||
getNowPlaying,
|
||||
getCoverArtUrl,
|
||||
getAvatarUrl,
|
||||
streamUrl,
|
||||
getAlbumInfo,
|
||||
getArtistInfo,
|
||||
|
||||
@@ -104,3 +104,26 @@ describe('getCoverArtUrl', () => {
|
||||
expect(url).not.toContain('_=')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAvatarUrl', () => {
|
||||
beforeEach(() => {
|
||||
// Mock localStorage values required by subsonic
|
||||
const localStorageMock = {
|
||||
getItem: vi.fn((key) => {
|
||||
const values = {
|
||||
username: 'testuser',
|
||||
'subsonic-token': 'testtoken',
|
||||
'subsonic-salt': 'testsalt',
|
||||
}
|
||||
return values[key] || null
|
||||
}),
|
||||
}
|
||||
Object.defineProperty(window, 'localStorage', { value: localStorageMock })
|
||||
})
|
||||
|
||||
it('should include username parameter', () => {
|
||||
const url = subsonic.getAvatarUrl('john')
|
||||
expect(url).toContain('getAvatar')
|
||||
expect(url).toContain('username=john')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user