UI improved

This commit is contained in:
Harwinder Sekhon
2026-07-27 13:58:47 -04:00
parent e78f2a81e0
commit 31b01a1a18
11 changed files with 3257 additions and 412 deletions
+43
View File
@@ -0,0 +1,43 @@
<?php
// Serves a cached course thumbnail — a frame captured from the course's first
// video at THUMBNAIL_SEEK_PERCENT, generated by the scanner (see
// generateThumbnails() in includes/functions.php). Looked up by folder ID
// only, mirroring stream.php's containment check; 404s (no thumbnail yet, or
// the id isn't a course) are expected and handled by the client falling back
// to its colour-block placeholder.
require_once __DIR__ . '/includes/auth.php';
require_once __DIR__ . '/includes/functions.php';
$userId = currentUserId();
if ($userId === null) {
http_response_code(403);
exit('Forbidden');
}
$courseId = (int)($_GET['course_id'] ?? 0);
$dir = realpath(THUMBNAILS_DIR);
$file = ($courseId > 0 && $dir !== false)
? realpath($dir . '/' . $courseId . '.jpg')
: false;
if ($dir === false || $file === false || !str_starts_with($file, $dir . DIRECTORY_SEPARATOR)
|| !is_file($file)) {
http_response_code(404);
exit('No thumbnail');
}
$mtime = filemtime($file);
$etag = '"' . md5($courseId . '-' . $mtime) . '"';
header('Cache-Control: private, max-age=86400');
header('ETag: ' . $etag);
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $mtime) . ' GMT');
if (($_SERVER['HTTP_IF_NONE_MATCH'] ?? null) === $etag) {
http_response_code(304);
exit;
}
header('Content-Type: image/jpeg');
header('Content-Length: ' . filesize($file));
readfile($file);