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'],
=h($msg)?>
=h($err)?>
Videos without input dir
No orphan videos.
=page_links('videos',$videoPage,$videoPages)?>
-Existing input dirs
No input directories yet.
No video yet=h(ucfirst($runStatus))?>Edit =h($meta['title'] ?: ($info['title'] ?? basename($d)))?>
=h($meta['date'])?>=h($meta['location'])?>No video
=nl2br(h($meta['description']), false)?>
=h(basename($d))?> · =h($info['file_count'] ?? count(list_files($d)))?> files · = $enabled ? 'Rendering enabled' : 'Rendering disabled' ?> · = $visible ? 'Shown' : 'Hidden' ?>= $running ? ' · '.h(ucfirst($runStatus)) : '' ?>
=page_links('edit',$editPage,$editPages)?>
+Existing input dirs
No input directories yet.
No video yet=h(ucfirst($runStatus))?>Edit =h($meta['title'] ?: ($info['title'] ?? basename($d)))?>
=h($meta['date'])?>=h($meta['location'])?>No videoPreview video
=nl2br(h($meta['description']), false)?>
=h(basename($d))?> · =h($info['file_count'] ?? count(list_files($d)))?> files · = $enabled ? 'Rendering enabled' : 'Rendering disabled' ?> · = $preview ? 'Preview enabled' : 'Preview disabled' ?> · = $visible ? 'Shown' : 'Hidden' ?>= $running ? ' · '.h(ucfirst($runStatus)) : '' ?>
=page_links('edit',$editPage,$editPages)?>
Edit input dir
in-dir/=h(basename($editDir))?>
This input directory is =h($editStatus)?>. Editing is disabled until the job completes.
@@ -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;