Skip to content

Commit b35fecc

Browse files
committed
Changes for project screenshots
1 parent f05c485 commit b35fecc

3 files changed

Lines changed: 12 additions & 14 deletions

File tree

apps/gif-service/src/gif-generator.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,29 +290,25 @@ export class GIFGenerator {
290290
return buffer;
291291
}
292292

293-
/** Render a representative still frame to a square PNG (Spectrum border preserved). */
293+
/** Render a representative still frame to a 4:3 PNG (Spectrum border included). */
294294
async generatePngFromTAP(tapData: Buffer, machineType: number = 48): Promise<Buffer> {
295295
const { frames } = await this.captureFrames(tapData, machineType, false);
296296
const frame = frames[frames.length - 1] ?? frames[0];
297297
if (!frame) throw new Error('No frame captured');
298298
return this.encodePng(frame);
299299
}
300300

301-
/** ffmpeg-encode one decoded frame to a square PNG, padding the (landscape) frame
302-
* with black so a rounded/tilted card crop never truncates the screen content. */
301+
/** ffmpeg-encode one decoded frame to a PNG at its native 4:3 size (border
302+
* included). The card fills it with object-fit: cover, so the outer border
303+
* is cropped to the square crop, not the screen. */
303304
private async encodePng(frame: Uint8Array): Promise<Buffer> {
304305
const width = this.decoder.getWidth();
305306
const height = this.decoder.getHeight();
306307
const rgba = this.decoder.decode(frame);
307308
const outPath = join(tmpdir(), `zxshot-${process.pid}-${Date.now()}.png`);
308309

309-
// Pad the landscape frame (border included) to a centred square so the
310-
// card's rounded corners clip black margin, not the Spectrum screen.
311-
const pad = 'pad=iw:iw:0:(iw-ih)/2:black';
312-
313310
const args = [
314311
'-f', 'rawvideo', '-pix_fmt', 'rgba', '-s', `${width}x${height}`, '-i', 'pipe:0',
315-
'-vf', pad,
316312
'-frames:v', '1',
317313
'-y', outPath,
318314
];

apps/gif-service/src/routes/screenshot.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const router = Router();
1212
const CACHE_DIR = process.env.SCREENSHOT_CACHE_DIR ?? '/cache';
1313
// Bump when the render output changes (size, padding, etc.) so cached PNGs
1414
// from older logic are superseded without manually clearing the volume.
15-
const RENDER_VERSION = 'v2';
15+
const RENDER_VERSION = 'v3';
1616
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1717

1818
// Single-flight: collapse concurrent requests for the same cache key onto one render.
@@ -83,10 +83,12 @@ router.get('/:id', async (req: Request, res: Response) => {
8383
res.send(png);
8484
} catch (err) {
8585
if (err instanceof CompileError) {
86-
// Unrenderable (e.g. zmac/sdcc not supported, or bad source) → web
87-
// falls back to the cartridge. Negative-cache to avoid re-rendering
88-
// it on every page load.
89-
res.setHeader('Cache-Control', 'public, max-age=3600');
86+
// Unrenderable (e.g. unsupported lang, or bad source) → web falls
87+
// back to the cartridge. Short negative-cache: enough to avoid
88+
// re-rendering on every page load, but it self-heals quickly after a
89+
// deploy that adds rendering support (the key is project-based, so a
90+
// server capability change can't otherwise invalidate it).
91+
res.setHeader('Cache-Control', 'public, max-age=300');
9092
res.status(422).end();
9193
return;
9294
}

apps/web/src/components/ProjectThumbnail.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default function ProjectThumbnail({ projectId, updatedAt }) {
3030
src={showShot ? `/screenshots/${projectId}.png?v=${version}` : "/assets/images/zx-square.png"}
3131
alt=""
3232
onError={showShot ? () => setFailed(true) : undefined}
33-
style={{ width: "94%", height: "94%", objectFit: "cover", margin: "3%" }}
33+
style={{ width: "100%", height: "100%", objectFit: "cover" }}
3434
/>
3535
</div>
3636
);

0 commit comments

Comments
 (0)