mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-08 02:17:25 +02:00
The UI decoded every blurhash into a 32x32 bitmap and stretched it to fill its container, so a non-square cover showed a full-box blur that collapsed into a letterboxed image the moment it loaded. On the album detail page the placeholder overhung the image by a third of the box height. A blurhash string carries no aspect ratio of its own, so the dimensions have to come from the server. artwork.width/height were already stored and read by nobody; they now surface on ItemImage as imageWidth/imageHeight, hydrated through the join that was already in place. Existing rows already carry them, so no migration or rescan is needed. A square request is padded rather than cropped, which aspect-fits the content inside the square the server returns. That made the grid a second instance of the same bug, so `square` now implies contain for the image as well as the placeholder, instead of the two renderers reading it differently.
66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package model_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/navidrome/navidrome/model"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("ItemImage JSON", func() {
|
|
It("exposes artwork state on an album", func() {
|
|
al := model.Album{ID: "al-1", Name: "Album"}
|
|
al.ImageHash = "0123456789abcdef"
|
|
al.BlurHash = "LEHV6nWB2yk8"
|
|
|
|
var out map[string]any
|
|
data, err := json.Marshal(al)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(json.Unmarshal(data, &out)).To(Succeed())
|
|
|
|
Expect(out).To(HaveKeyWithValue("imageHash", "0123456789abcdef"))
|
|
Expect(out).To(HaveKeyWithValue("blurHash", "LEHV6nWB2yk8"))
|
|
})
|
|
|
|
// Clients decode the blurhash into a bitmap of their choosing, so without the dimensions they
|
|
// cannot know the placeholder's shape and default to a square.
|
|
It("exposes the image dimensions alongside the blurhash", func() {
|
|
al := model.Album{ID: "al-3", Name: "Album"}
|
|
al.BlurHash = "LEHV6nWB2yk8"
|
|
al.ImageWidth, al.ImageHeight = 1200, 800
|
|
|
|
var out map[string]any
|
|
data, err := json.Marshal(al)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(json.Unmarshal(data, &out)).To(Succeed())
|
|
|
|
Expect(out).To(HaveKeyWithValue("imageWidth", BeNumerically("==", 1200)))
|
|
Expect(out).To(HaveKeyWithValue("imageHeight", BeNumerically("==", 800)))
|
|
})
|
|
|
|
It("omits artwork state when the entity has none", func() {
|
|
var out map[string]any
|
|
data, err := json.Marshal(model.Album{ID: "al-2", Name: "Album"})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(json.Unmarshal(data, &out)).To(Succeed())
|
|
|
|
Expect(out).ToNot(HaveKey("imageHash"))
|
|
Expect(out).ToNot(HaveKey("blurHash"))
|
|
Expect(out).ToNot(HaveKey("imageAbsent"))
|
|
Expect(out).ToNot(HaveKey("imageWidth"))
|
|
Expect(out).ToNot(HaveKey("imageHeight"))
|
|
})
|
|
|
|
It("exposes known-absent artwork so clients can skip the request", func() {
|
|
ar := model.Artist{ID: "ar-1", Name: "Artist"}
|
|
ar.ImageAbsent = true
|
|
|
|
var out map[string]any
|
|
data, err := json.Marshal(ar)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(json.Unmarshal(data, &out)).To(Succeed())
|
|
|
|
Expect(out).To(HaveKeyWithValue("imageAbsent", true))
|
|
})
|
|
})
|