feat: upload progress bar — fieldset layout, accent colors, file name display, completion animation, 800ms redirect delay; decorelate formats from fichiers; server-side poll via token; bump PeerTube embed audio player

This commit is contained in:
Pontoporeia
2026-05-11 13:12:36 +02:00
parent cdec3e96a6
commit 927ee2fe2a
12 changed files with 420 additions and 212 deletions

View File

@@ -161,7 +161,7 @@ class ThesisEditController
* the transaction is still open, but this method rolls
* back internally before re-throwing).
*/
public function save(int $thesisId, array $post, array $files): void
public function save(int $thesisId, array $post, array $files, ?string $progressToken = null): void
{
if ($thesisId <= 0) {
throw new InvalidArgumentException('ID de TFE invalide.');
@@ -440,8 +440,8 @@ class ThesisEditController
// ── PeerTube video / audio uploads (from FilePond queue) ──────────────
$qPTVideo = $this->extractFilesSubArray($queueFiles, 'peertube_video');
$qPTAudio = $this->extractFilesSubArray($queueFiles, 'peertube_audio');
$this->handlePeerTubeQueueFiles($thesisId, trim($post['titre'] ?? ''), $qPTVideo, 'video');
$this->handlePeerTubeQueueFiles($thesisId, trim($post['titre'] ?? ''), $qPTAudio, 'audio');
$this->handlePeerTubeQueueFiles($thesisId, trim($post['titre'] ?? ''), $qPTVideo, 'video', $progressToken);
$this->handlePeerTubeQueueFiles($thesisId, trim($post['titre'] ?? ''), $qPTAudio, 'audio', $progressToken);
// ── Website URL — add or update ──────────────────────────────────────
$this->handleWebsiteUrl($thesisId, $post);
@@ -583,7 +583,7 @@ class ThesisEditController
* @param array|null $uploads Flat $_FILES-style array from extractFilesSubArray().
* @param string $fileType 'video' or 'audio'.
*/
private function handlePeerTubeQueueFiles(int $thesisId, string $title, ?array $uploads, string $fileType): void
private function handlePeerTubeQueueFiles(int $thesisId, string $title, ?array $uploads, string $fileType, ?string $progressToken = null): void
{
if (!$uploads || !is_array($uploads['name'] ?? null)) {
return;
@@ -594,17 +594,23 @@ class ThesisEditController
return;
}
$label = $fileType === 'video' ? 'Vidéo' : 'Audio';
$count = count($uploads['name']);
for ($i = 0; $i < $count; $i++) {
if (($uploads['error'][$i] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
continue;
}
$fileName = $uploads['name'][$i];
if ($progressToken) {
PeerTubeService::writeProgress($progressToken, 'peertube', 25 + (int)(($i / max($count, 1)) * 74), $label . ' : ' . $fileName);
}
try {
$result = PeerTubeService::upload(
$this->db,
$uploads['tmp_name'][$i],
$uploads['name'][$i],
$fileName,
$title,
''
);
@@ -614,7 +620,7 @@ class ThesisEditController
$thesisId,
$fileType,
$storedPath,
basename($uploads['name'][$i]),
basename($fileName),
$uploads['size'][$i],
$uploads['type'][$i] ?? 'application/octet-stream',
null,

View File

@@ -436,4 +436,30 @@ class PeerTubeService
return ['status' => $status, 'body' => (string)$responseBody, 'headers' => $responseHeaders];
}
// -------------------------------------------------------------------------
// Progress reporting (for upload-progress.js polling)
// -------------------------------------------------------------------------
/**
* Write upload progress to a temp file polled by the progress endpoint.
*/
public static function writeProgress(string $token, string $stage, int $pct, string $file = ''): void
{
$progressFile = sys_get_temp_dir() . '/xamxam_upload_' . $token . '.json';
file_put_contents($progressFile, json_encode([
'stage' => $stage,
'pct' => $pct,
'file' => $file,
]), LOCK_EX);
}
/**
* Remove the progress file for a given token.
*/
public static function clearProgress(string $token): void
{
$progressFile = sys_get_temp_dir() . '/xamxam_upload_' . $token . '.json';
@unlink($progressFile);
}
}