diff --git a/ts/live.php b/ts/live.php
index b8ca88c..ee23cca 100644
--- a/ts/live.php
+++ b/ts/live.php
@@ -1,7 +1,7 @@
@@ -114,8 +126,15 @@ function render_edit(): never {
@@ -130,6 +149,22 @@ function render_edit(): never {
// FILE SERVER (default route)
// =============================================================================
+function serve_png(): never {
+ require_auth();
+ $f = $_GET['img'] ?? '';
+ if (!safe_filename($f)) {
+ http_response_code(400); exit('Invalid filename.');
+ }
+ $path = png_path($f);
+ if (!file_exists($path)) {
+ http_response_code(404); exit('No preview.');
+ }
+ header('Content-Type: image/png');
+ header('Content-Length: ' . filesize($path));
+ readfile($path);
+ exit;
+}
+
function serve_active_file(): never {
$active = get_active();
@@ -158,11 +193,12 @@ function serve_active_file(): never {
// ROUTES
// =============================================================================
//
-// GET /live.php -> serve active .bin file
+// GET /live.php -> serve active .bin file
// GET /live.php?login -> login page
// POST /live.php?login -> process login
-// GET /live.php?edit -> file picker [auth required]
-// POST /live.php?edit -> set active file [auth required]
+// GET /live.php?edit -> file picker [auth required]
+// POST /live.php?edit -> set active file [auth required]
+// GET /live.php?img=x.bin -> serve x.png preview [auth required]
//
// =============================================================================
@@ -174,5 +210,6 @@ match (true) {
$method === 'POST' && $route === 'edit' => action_set_file(),
$method === 'GET' && $route === 'login' => render_login(),
$method === 'GET' && $route === 'edit' => render_edit(),
+ $method === 'GET' && $route === 'img' => serve_png(),
default => serve_active_file(),
};