From 8327d5e7099847d61b890123221d7e729dc43f5c Mon Sep 17 00:00:00 2001 From: hbrain Date: Wed, 27 May 2026 08:41:15 +0200 Subject: [PATCH] Feat: Add toast notification for edit button when job is running --- new.php | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/new.php b/new.php index 13abc59..d928d94 100644 --- a/new.php +++ b/new.php @@ -138,7 +138,7 @@ function unique_input_dir($base, $slug){ function input_dir_signature($dir){ $entries = []; foreach (scandir($dir) ?: [] as $file) { - if ($file === '.' || $file === '..' || in_array($file, ['.movmaker-state.json','.movmaker-enabled','.mvlog-hidden'], true)) continue; + if ($file === '.' || $file === '..' || in_array($file, ['.movmaker-state.json','.movmaker-enabled','.movmaker-preview','.mvlog-hidden'], true)) continue; if ($file === '.movmaker-lock') continue; $path = $dir . '/' . $file; if (is_file($path)) $entries[] = [$file, filesize($path), filemtime($path)]; @@ -217,16 +217,26 @@ function set_input_dir_enabled($dir, $enabled){ if ($enabled) { file_put_contents($path, "enabled\n"); chmod($path, 0664); } elseif (is_file($path)) unlink($path); } +function input_dir_preview($dir){ return is_file($dir . '/.movmaker-preview'); } +function set_input_dir_preview($dir, $preview){ + $path = $dir . '/.movmaker-preview'; + if ($preview) { file_put_contents($path, "preview\n"); chmod($path, 0664); } + elseif (is_file($path)) unlink($path); +} function input_dir_visible($dir){ return !is_file($dir . '/.mvlog-hidden'); } function set_input_dir_visible($dir, $visible){ $path = $dir . '/.mvlog-hidden'; if ($visible) { if (is_file($path)) unlink($path); } else { file_put_contents($path, "hidden\n"); chmod($path, 0664); } } -function input_dir_output($dir){ +function input_dir_state($dir){ $stateFile = $dir . '/.movmaker-state.json'; $state = is_file($stateFile) ? json_decode((string)file_get_contents($stateFile), true) : []; - return is_array($state) ? basename((string)($state['output'] ?? '')) : ''; + return is_array($state) ? $state : []; +} +function input_dir_output($dir){ + $state = input_dir_state($dir); + return basename((string)($state['output'] ?? '')); } function cached_video_metadata($output, $fallback){ $meta = ['title'=>$fallback['title'] ?? '', 'date'=>$fallback['date'] ?? '', 'location'=>$fallback['place'] ?? '', 'description'=>$fallback['description'] ?? '']; @@ -293,6 +303,7 @@ try { chmod($dir, 02775); write_data($dir, $_POST); set_input_dir_enabled($dir, false); + set_input_dir_preview($dir, false); set_input_dir_visible($dir, false); $msg = "Created movmaker input directory: in-dir/$slug"; $_GET['edit'] = $slug; @@ -300,14 +311,34 @@ try { $dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? ''); $enabledNow = !empty($_POST['enabled']); set_input_dir_enabled($dir, $enabledNow); - if (!empty($_POST['ajax'])) ajax_json(['ok'=>true, 'enabled'=>$enabledNow, 'dir'=>basename($dir)]); + if ($enabledNow) set_input_dir_preview($dir, false); + $state = input_dir_state($dir); + $output = basename((string)($state['output'] ?? '')); + $canShow = $output !== '' && is_file($config['videos_dir'].'/'.$output) && !input_dir_preview($dir); + if (!$canShow) set_input_dir_visible($dir, false); + if (!empty($_POST['ajax'])) ajax_json(['ok'=>true, 'enabled'=>$enabledNow, 'preview'=>input_dir_preview($dir), 'visible'=>input_dir_visible($dir) && $canShow, 'can_show'=>$canShow, 'dir'=>basename($dir)]); header('Location: new.php?tab=edit&msg=' . rawurlencode(($enabledNow ? 'Enabled rendering for: in-dir/' : 'Disabled rendering for: in-dir/') . basename($dir))); exit; + } elseif ($action === 'set_preview') { + $dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? ''); + $previewNow = !empty($_POST['preview']); + set_input_dir_preview($dir, $previewNow); + if ($previewNow) { set_input_dir_enabled($dir, false); set_input_dir_visible($dir, false); } + $state = input_dir_state($dir); + $output = basename((string)($state['output'] ?? '')); + $canShow = $output !== '' && is_file($config['videos_dir'].'/'.$output) && !input_dir_preview($dir); + if (!empty($_POST['ajax'])) ajax_json(['ok'=>true, 'preview'=>$previewNow, 'enabled'=>input_dir_enabled($dir), 'visible'=>input_dir_visible($dir) && $canShow, 'can_show'=>$canShow, 'dir'=>basename($dir)]); + header('Location: new.php?tab=edit&msg=' . rawurlencode(($previewNow ? 'Enabled preview for: in-dir/' : 'Disabled preview for: in-dir/') . basename($dir))); + exit; } elseif ($action === 'set_visible') { $dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? ''); $visibleNow = !empty($_POST['visible']); - set_input_dir_visible($dir, $visibleNow); - if (!empty($_POST['ajax'])) ajax_json(['ok'=>true, 'visible'=>$visibleNow, 'dir'=>basename($dir)]); + $state = input_dir_state($dir); + $output = basename((string)($state['output'] ?? '')); + $canShow = $output !== '' && is_file($config['videos_dir'].'/'.$output) && !input_dir_preview($dir); + if ($visibleNow && !$canShow) throw new RuntimeException('Only finished full-quality videos can be shown.'); + set_input_dir_visible($dir, $visibleNow && $canShow); + if (!empty($_POST['ajax'])) ajax_json(['ok'=>true, 'visible'=>input_dir_visible($dir) && $canShow, 'can_show'=>$canShow, 'dir'=>basename($dir)]); header('Location: new.php?tab=edit&msg=' . rawurlencode(($visibleNow ? 'Shown: in-dir/' : 'Hidden: in-dir/') . basename($dir))); exit; } elseif ($action === 'update') { @@ -376,7 +407,7 @@ if ($editName !== '') { try { $editDir = safe_input_dir($config['uploads_dir'],

Videos without input dir

No orphan videos.


MB
-

Existing input dirs

No input directories yet.

No video yet

No video

· files · ·

+

Existing input dirs

No input directories yet.

No video yet

No videoPreview video

· files · · ·

Edit input dir

in-dir/

This input directory is . Editing is disabled until the job completes.

Edit input dir

in-dir/

Files and captions

No caption for audio files

Add new movie input

@@ -415,9 +446,9 @@ document.querySelectorAll('.admin-switches input[type="checkbox"]').forEach(func const action=data.get('action'); const titleEl=input.closest('.video-info')?.querySelector('h2'); const title=(titleEl?.textContent || '').trim() || json.dir || data.get('dir') || 'input dir'; - const quotedTitle='“'+title+'”'; - if(action==='set_visible') showToast((input.checked?'Shown: ':'Hidden: ')+quotedTitle, true); + const quotedTitle="'" + title + "'";if(action==='set_visible') showToast((input.checked?'Shown: ':'Hidden: ')+quotedTitle, true); else if(action==='set_enabled') showToast((input.checked?'Run enabled: ':'Run disabled: ')+quotedTitle, true); + else if(action==='set_preview') showToast((input.checked?'Preview enabled: ':'Preview disabled: ')+quotedTitle, true); else showToast('Updated '+quotedTitle, true); }catch(e){ input.checked=previous;