Size HTML firmware previews by board (480x320 for 3.5).

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-23 18:45:24 +08:00
parent 2dd97f95ad
commit cf617592d4
4 changed files with 26 additions and 9 deletions

View File

@@ -31,7 +31,13 @@ export function FirmwareCard({
: "border-[var(--line)] bg-[rgba(0,0,0,0.22)] hover:-translate-y-0.5 hover:border-[rgba(240,197,10,0.35)] hover:bg-[rgba(240,197,10,0.04)]"
)}
>
<div className="relative aspect-[4/3] w-full overflow-hidden border-b border-[var(--line)]">
<div
className={
fw.boardId === "esp32-3248s035"
? "relative aspect-[3/2] w-full overflow-hidden border-b border-[var(--line)]"
: "relative aspect-[4/3] w-full overflow-hidden border-b border-[var(--line)]"
}
>
<FirmwarePreview fw={fw} />
<div className="pointer-events-none absolute bottom-2 left-2 flex gap-1">
{hasPreview && (

View File

@@ -36,7 +36,13 @@ export function FirmwareDetail({
</h3>
</div>
<div className="aspect-[4/3] w-full border-b border-[var(--line)] bg-black/40">
<div
className={
fw.boardId === "esp32-3248s035"
? "aspect-[3/2] w-full border-b border-[var(--line)] bg-black/40"
: "aspect-[4/3] w-full border-b border-[var(--line)] bg-black/40"
}
>
{fw.media.preview ? (
<FirmwarePreview fw={fw} />
) : fw.media.video ? (

View File

@@ -3,12 +3,10 @@
import { useEffect, useRef, useState } from "react";
import { useTranslations } from "next-intl";
import type { FirmwareInfo } from "@/lib/firmware";
import { boardPreviewSize } from "@/lib/boards";
import { sensorMediaForProject } from "@/lib/sensor-media";
import { cn } from "@/lib/utils";
const SCREEN_W = 320;
const SCREEN_H = 240;
type Tab = "ui" | "sensor";
/** On-device HTML UI mock + optional hardware still, switchable via tabs. */
@@ -24,6 +22,7 @@ export function FirmwarePreview({
const t = useTranslations("firmware");
const hostRef = useRef<HTMLDivElement>(null);
const [scale, setScale] = useState(1);
const { w: screenW, h: screenH } = boardPreviewSize(fw.boardId);
const sensor = sensorMediaForProject(fw.project);
const hasUi = Boolean(fw.media.preview);
const [tab, setTab] = useState<Tab>(hasUi ? "ui" : "sensor");
@@ -39,14 +38,14 @@ export function FirmwarePreview({
const update = () => {
const { width, height } = el.getBoundingClientRect();
if (width <= 0 || height <= 0) return;
setScale(Math.min(width / SCREEN_W, height / SCREEN_H));
setScale(Math.min(width / screenW, height / screenH));
};
update();
const ro = new ResizeObserver(update);
ro.observe(el);
return () => ro.disconnect();
}, [fw.media.preview, tab]);
}, [fw.media.preview, tab, screenW, screenH]);
const showTabs = hasUi && Boolean(sensor);
@@ -113,8 +112,8 @@ export function FirmwarePreview({
<iframe
title={title || `${fw.name} UI preview`}
src={fw.media.preview!}
width={SCREEN_W}
height={SCREEN_H}
width={screenW}
height={screenH}
loading="lazy"
sandbox="allow-scripts"
tabIndex={-1}

View File

@@ -60,3 +60,9 @@ export function resolveBoardId(boardField: string | null | undefined): string {
export function getBoard(id: string): BoardDefinition | undefined {
return BOARDS.find((b) => b.id === id);
}
/** Logical UI resolution used by HTML firmware previews (matches UX/UY). */
export function boardPreviewSize(boardId: string): { w: number; h: number } {
if (boardId === "esp32-3248s035") return { w: 480, h: 320 };
return { w: 320, h: 240 };
}