Decode the device's rendered 4bpp Spectra-6 .bin into a PNG (cached
next to the .bin) so the home-screen preview matches the dithered
6-color output the e-ink actually displays.
- New endpoint: GET /api/devices/{id}/preview
- Expose currentImageId on device JSON
- HomeView passes preview URL to FrameCard for both single and compact layouts
- Drive-by: fix vite.config.ts to import defineConfig from vitest/config
so the build no longer fails on the unknown `test` property; remove
unused useUploadStore import in HomeView test
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ const makeDevice = (overrides: Partial<Device> = {}): Device => ({
|
||||
linkedAt: '2026-01-01T00:00:00Z',
|
||||
lastSeenAt: null,
|
||||
lockedImageId: null,
|
||||
currentImageId: null,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ const makeDevice = (overrides: Partial<Device> = {}): Device => ({
|
||||
linkedAt: '2026-01-01T00:00:00Z',
|
||||
lastSeenAt: null,
|
||||
lockedImageId: null,
|
||||
currentImageId: null,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { setActivePinia, createPinia } from 'pinia'
|
||||
import { useDevicesStore } from '@/stores/devices'
|
||||
import { useUploadStore } from '@/stores/upload'
|
||||
import HomeView from '@/views/HomeView.vue'
|
||||
import type { Device } from '@/types'
|
||||
|
||||
@@ -70,6 +69,7 @@ const makeDevice = (overrides: Partial<Device> = {}): Device => ({
|
||||
linkedAt: '2026-01-01T00:00:00Z',
|
||||
lastSeenAt: null,
|
||||
lockedImageId: null,
|
||||
currentImageId: null,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ const makeDevice = (overrides: Partial<Device> = {}): Device => ({
|
||||
linkedAt: '2026-01-01T00:00:00Z',
|
||||
lastSeenAt: null,
|
||||
lockedImageId: null,
|
||||
currentImageId: null,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface Device {
|
||||
linkedAt: string
|
||||
lastSeenAt: string | null
|
||||
lockedImageId: number | null
|
||||
currentImageId: number | null
|
||||
}
|
||||
|
||||
export interface CropParams {
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
size="large"
|
||||
:status="deviceStatus(devicesStore.devices[0])"
|
||||
:orientation="devicesStore.devices[0].orientation"
|
||||
:thumbnailUrl="previewUrl(devicesStore.devices[0])"
|
||||
@add-photo="onAddPhoto"
|
||||
@edit="onEdit"
|
||||
/>
|
||||
@@ -44,6 +45,7 @@
|
||||
size="compact"
|
||||
:status="deviceStatus(device)"
|
||||
:orientation="device.orientation"
|
||||
:thumbnailUrl="previewUrl(device)"
|
||||
@add-photo="onAddPhoto"
|
||||
@edit="onEdit"
|
||||
/>
|
||||
@@ -109,6 +111,11 @@ function deviceStatus(device: Device): 'ok' | 'offline' {
|
||||
const windowMs = Math.max(device.rotationIntervalMinutes * 2 * 60_000, 30 * 60_000)
|
||||
return seenMs <= windowMs ? 'ok' : 'offline'
|
||||
}
|
||||
|
||||
function previewUrl(device: Device): string | undefined {
|
||||
const imageId = device.lockedImageId ?? device.currentImageId
|
||||
return imageId ? `/api/devices/${device.id}/preview?v=${imageId}` : undefined
|
||||
}
|
||||
import FrameCard from '@/components/FrameCard.vue'
|
||||
import BaseBottomSheet from '@/components/BaseBottomSheet.vue'
|
||||
import BaseButton from '@/components/BaseButton.vue'
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/// <reference types="vitest" />
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user