Merge branch 'master' into fix-forceformat-directplay

This commit is contained in:
Deluan Quintão 2026-09-09 17:38:56 -04:00 • committed by GitHub
commit e7b449b805
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 30 additions and 10 deletions

View file

@ -187,7 +187,7 @@ LABEL org.opencontainers.image.source="https://github.com/navidrome/navidrome"
# - libwebp + symlinks: enables native WebP encoding via purego/dlopen
# The mesa/LLVM stack mpv pulls in for video output is dropped in this same layer,
# otherwise the deleted bytes still ship in the image.
RUN apk add -U --no-cache ffmpeg mpv sqlite libwebp libwebpdemux libwebpmux && \
RUN apk add -U --no-cache curl ffmpeg mpv sqlite libwebp libwebpdemux libwebpmux && \
for lib in libwebp libwebpdemux libwebpmux; do \
target=$(ls /usr/lib/$lib.so.* 2>/dev/null | head -1) && \
[ -n "$target" ] && ln -sf "$target" /usr/lib/$lib.so; \

View file

@ -34,8 +34,8 @@ func imageSize(maxWidth, maxHeight int) int {
}
func (api *Router) getItemImage(w http.ResponseWriter, r *http.Request) {
// Public endpoint, like real Jellyfin's image routes: clients fetch cover URLs without credentials
// and item ids are unguessable, so resolution runs elevated to bypass the visibility filter.
// Public, like Jellyfin's own image routes: clients build cover URLs without credentials, and
// upstream resolves them with no visibility check either (LibraryManager.ItemIsVisible, null user).
ctx := request.WithUser(r.Context(), model.User{IsAdmin: true})
itemId, ok := itemIDParam(w, r, "itemId")
if !ok {

View file

@ -8,8 +8,8 @@ import {
useUnselectAll,
} from 'react-admin'
import { useSelector } from 'react-redux'
import SyncIcon from '@material-ui/icons/Sync'
import CachedIcon from '@material-ui/icons/Cached'
import { GiMagnifyingGlass } from 'react-icons/gi'
import { VscSync } from 'react-icons/vsc'
import subsonic from '../subsonic'
const LibraryScanButton = ({ fullScan, selectedIds, className }) => {
@ -54,7 +54,7 @@ const LibraryScanButton = ({ fullScan, selectedIds, className }) => {
? translate('resources.library.actions.fullScan')
: translate('resources.library.actions.quickScan')
const icon = fullScan ? <CachedIcon /> : <SyncIcon />
const icon = fullScan ? <GiMagnifyingGlass /> : <VscSync />
return (
<Button

View file

@ -598,11 +598,9 @@ const NautilineTheme = {
},
},
NDAlbumGridView: {
albumContainer: {
link: {
borderRadius: radii.md,
'& img': {
borderRadius: radii.md,
},
overflow: 'hidden',
},
albumTitle: {
fontWeight: 600,

View file

@ -12,3 +12,25 @@ describe('NDPlaylistDetails styles', () => {
},
)
})
describe('NDAlbumGridView styles', () => {
const themeEntries = Object.entries(themes)
// The hover overlay is a sibling of the image, so it keeps square corners.
it.each(themeEntries)(
'%s should not round the grid cover image on its own',
(themeName, theme) => {
const container = theme.overrides?.NDAlbumGridView?.albumContainer
expect(container?.['& img']?.borderRadius).toBeUndefined()
},
)
it.each(themeEntries)(
'%s should clip the grid cover link when it is rounded',
(themeName, theme) => {
const link = theme.overrides?.NDAlbumGridView?.link
if (!link?.borderRadius) return
expect(link.overflow).toBe('hidden')
},
)
})