Two related bugs that surfaced on the first 13.3" device's first photo: 1) Web-UI portrait preview was 90° sideways. DeviceApiController:: renderBinToPng rotated whenever the device was Portrait — correct for V1 (landscape-native, Portrait => renderer rotated, so preview un-rotates) but wrong for V2 (portrait-native — the renderer doesn't rotate, so the preview shouldn't either). Now mirrors the render-pipeline check: rotate only when `orientation !== model->nativeOrientation()`. Two new functional tests pin the V2 portrait and V2 landscape PNG dimensions to guard against regressions. 2) Cropped photo letterboxed on the 13.3" panel. CropEditor / StickerCanvas / FrameCard had V1 dimensions hardcoded (1600×960 = 5:3 aspect). V2 is 4:3 (1200×1600 portrait / 1600×1200 landscape), so a "full crop" came out the wrong shape and the server's white-canvas composite added bars. New `panelDims(model, orientation)` helper in @/types is the single source of truth on the frontend; matches DeviceModel::width/height on the server. Threaded `model` through Device serializer → Device type → UploadView → CropEditor / StickerCanvas, and HomeView → FrameCard. FrameCard tests updated to cover all four model × orientation placeholders. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -146,19 +146,35 @@ describe('FrameCard', () => {
|
||||
expect(wrapper.emitted('edit')![0]).toEqual([1])
|
||||
})
|
||||
|
||||
it('reserves a 5:3 aspect placeholder when no thumbnail is present (landscape)', () => {
|
||||
it('reserves a V1 landscape (1600 × 960) placeholder when no thumbnail is present', () => {
|
||||
const wrapper = mount(FrameCard, {
|
||||
props: { ...defaultProps, size: 'large', orientation: 'landscape' },
|
||||
props: { ...defaultProps, size: 'large', orientation: 'landscape', model: 'v1' },
|
||||
})
|
||||
const empty = wrapper.find('.frame-card__empty-preview')
|
||||
expect(empty.attributes('style')).toMatch(/aspect-ratio:\s*5\s*\/\s*3/)
|
||||
expect(empty.attributes('style')).toMatch(/aspect-ratio:\s*1600\s*\/\s*960/)
|
||||
})
|
||||
|
||||
it('reserves a 3:5 aspect placeholder when no thumbnail is present (portrait)', () => {
|
||||
it('reserves a V1 portrait (960 × 1600) placeholder when no thumbnail is present', () => {
|
||||
const wrapper = mount(FrameCard, {
|
||||
props: { ...defaultProps, size: 'large', orientation: 'portrait' },
|
||||
props: { ...defaultProps, size: 'large', orientation: 'portrait', model: 'v1' },
|
||||
})
|
||||
const empty = wrapper.find('.frame-card__empty-preview')
|
||||
expect(empty.attributes('style')).toMatch(/aspect-ratio:\s*3\s*\/\s*5/)
|
||||
expect(empty.attributes('style')).toMatch(/aspect-ratio:\s*960\s*\/\s*1600/)
|
||||
})
|
||||
|
||||
it('reserves a V2 portrait (1200 × 1600) placeholder when no thumbnail is present', () => {
|
||||
const wrapper = mount(FrameCard, {
|
||||
props: { ...defaultProps, size: 'large', orientation: 'portrait', model: 'v2' },
|
||||
})
|
||||
const empty = wrapper.find('.frame-card__empty-preview')
|
||||
expect(empty.attributes('style')).toMatch(/aspect-ratio:\s*1200\s*\/\s*1600/)
|
||||
})
|
||||
|
||||
it('reserves a V2 landscape (1600 × 1200) placeholder when no thumbnail is present', () => {
|
||||
const wrapper = mount(FrameCard, {
|
||||
props: { ...defaultProps, size: 'large', orientation: 'landscape', model: 'v2' },
|
||||
})
|
||||
const empty = wrapper.find('.frame-card__empty-preview')
|
||||
expect(empty.attributes('style')).toMatch(/aspect-ratio:\s*1600\s*\/\s*1200/)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user