Responsive mobile layout and header word sizing
This commit is contained in:
parent
1f056fdc7c
commit
4d52eee70e
3 changed files with 35 additions and 49 deletions
65
new.php
65
new.php
|
|
@ -217,11 +217,25 @@ 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 input_dir_preview($dir){
|
||||
if (is_file($dir . '/.movmaker-preview')) return true;
|
||||
$stateFile = $dir . '/.movmaker-state.json';
|
||||
if (!is_file($stateFile)) return false;
|
||||
$state = json_decode((string)file_get_contents($stateFile), true);
|
||||
return is_array($state) && !empty($state['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);
|
||||
$stateFile = $dir . '/.movmaker-state.json';
|
||||
$state = is_file($stateFile) ? json_decode((string)file_get_contents($stateFile), true) : [];
|
||||
if (!is_array($state)) $state = [];
|
||||
$state['preview'] = (bool)$preview;
|
||||
$state['preview_updated_at'] = gmdate('c');
|
||||
file_put_contents($stateFile, json_encode($state, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "
|
||||
");
|
||||
chmod($stateFile, 0664);
|
||||
}
|
||||
function input_dir_visible($dir){ return !is_file($dir . '/.mvlog-hidden'); }
|
||||
function set_input_dir_visible($dir, $visible){
|
||||
|
|
@ -341,7 +355,6 @@ try {
|
|||
$dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? '');
|
||||
$enabledNow = !empty($_POST['enabled']);
|
||||
set_input_dir_enabled($dir, $enabledNow);
|
||||
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);
|
||||
|
|
@ -445,12 +458,12 @@ if ($editName !== '') { try { $editDir = safe_input_dir($config['uploads_dir'],
|
|||
$runningJobs = active_worker_jobs($config);
|
||||
?>
|
||||
<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Admin - <?=h($config['site_name'])?></title><link rel="icon" type="image/png" href="assets/img/moto_travel.png"><link rel="stylesheet" href="style.css"></head><body>
|
||||
<header class="site-header admin-header"><div class="brand-wrap"><a class="header-logo" href="index.php" aria-label="MVLog home"><img src="assets/img/moto_travel.png" alt=""></a><a class="brand" href="index.php"><h1>MVLog Admin</h1><p>Bubulescu.Org</p></a></div></header>
|
||||
<header class="site-header admin-header"><div class="brand-wrap"><a class="header-logo" href="index.php" aria-label="MVLog home"><img src="assets/img/moto_travel.png" alt=""></a><a class="brand" href="index.php"><h1>MVLog <span class="admin-word">Admin</span></h1><p>Bubulescu.Org</p></a></div></header>
|
||||
<main>
|
||||
<?php if($err): ?><div class="err"><?=h($err)?></div><?php endif; ?>
|
||||
|
||||
<?php if($tab==='videos'): ?><section><h2>Videos without input dir</h2><?php if(!$orphanVideos): ?><p>No orphan videos.</p><?php endif; ?><div class="admin-list"><?php foreach($orphanVideosPage as $v): $vn=basename($v); ?><form method="post" class="admin-item" onsubmit="return confirm('Delete this generated video?') js-ajax-form"><div><strong><?=h($vn)?></strong><br><span><?=h(round(filesize($v)/1048576,1))?> MB</span></div><input type="hidden" name="action" value="delete_video"><input type="hidden" name="video" value="<?=h($vn)?>"><button type="submit">Delete video</button></form><?php endforeach; ?></div><?=page_links('videos',$videoPage,$videoPages)?></section><?php endif; ?>
|
||||
<?php if($tab==='edit' && !$editDir): ?><section><h2>Existing input dirs</h2><?php if(!$dirs): ?><p>No input directories yet.</p><?php endif; ?><div class="admin-list video-list"><?php foreach($dirsPage as $d): $runStatus=input_dir_status($d); $running=input_dir_running($d); $enabled=input_dir_enabled($d); $preview=input_dir_preview($d); $state=input_dir_state($d); $fullOutput=basename((string)($state['output'] ?? '')); $previewOutput=basename((string)($state['preview_output'] ?? '')); $hasFullVideo=$fullOutput !== '' && is_file($config['videos_dir'].'/'.$fullOutput); $hasPreviewVideo=$previewOutput !== '' && is_file($config['videos_dir'].'/'.$previewOutput); $displayOutput=($preview && $hasPreviewVideo) ? $previewOutput : ($hasFullVideo ? $fullOutput : ($hasPreviewVideo ? $previewOutput : '')); $hasVideo=$displayOutput !== ''; $displayVideoPath=$hasVideo ? $config['videos_dir'].'/'.$displayOutput : ''; $previewVideo=$hasVideo && $displayOutput === $previewOutput; $canShow=$hasFullVideo && !$preview; $visible=$canShow && input_dir_visible($d); $info=$dirInfo[basename($d)] ?? input_dir_info($d); $data=read_data($d); $meta=cached_video_metadata($displayOutput, $data); ?><article class="video-row admin-video-row<?= $visible ? ' shown' : '' ?>" data-job="<?=h(basename($d))?>"><div><?php if($hasVideo): ?><video controls controlsList="nodownload" oncontextmenu="return false" preload="metadata" src="<?=h($config['public_videos'].'/'.rawurlencode($displayOutput))?>"></video><?php else: ?><div class="video-placeholder"><img src="assets/img/moto_travel.png" alt=""><span>No video yet</span></div><?php endif; ?></div><div class="video-info"><div class="admin-row-top"><div class="admin-switches"><form method="post" class="inline-form"><input type="hidden" name="action" value="set_preview"><input type="hidden" name="dir" value="<?=h(basename($d))?>"><label class="switch-label"><input type="checkbox" name="preview" value="1" <?=$preview?'checked':''?>><span class="switch-ui" aria-hidden="true"></span><span class="switch-text">Preview</span></label></form><form method="post" class="inline-form"><input type="hidden" name="action" value="set_enabled"><input type="hidden" name="dir" value="<?=h(basename($d))?>"><label class="switch-label"><input type="checkbox" name="enabled" value="1" <?=$enabled?'checked':''?>><span class="switch-ui" aria-hidden="true"></span><span class="switch-text">Render</span></label></form><form method="post" class="inline-form"><input type="hidden" name="action" value="set_visible"><input type="hidden" name="dir" value="<?=h(basename($d))?>"><label class="switch-label"><input type="checkbox" name="visible" value="1" <?=$visible?'checked':''?> <?=!$canShow?'disabled':''?>><span class="switch-ui" aria-hidden="true"></span><span class="switch-text">Show</span></label></form><?php if($hasVideo): ?><time class="admin-time" title="Video created at"><?=h(date('d.m.Y H:i', filemtime($displayVideoPath)))?></time><?php endif; ?></div><div class="admin-actions"><?php if($running): ?><span class="button disabled" title="Rendering now" data-edit-action="1">Rendering</span><?php else: ?><a class="button" href="?edit=<?=rawurlencode(basename($d))?>" data-edit-action="1" data-edit-href="?edit=<?=rawurlencode(basename($d))?>">Edit</a><?php endif; ?></div></div><h2><?=h($meta['title'] ?: ($info['title'] ?? basename($d)))?></h2><p class="meta"><?php if($meta['date']): ?><span><?=h($meta['date'])?></span><?php endif; ?><?php if($meta['location']): ?><span><?=h($meta['location'])?></span><?php endif; ?><?php if(!$hasVideo): ?><span>No video</span><?php endif; ?><?php if($previewVideo): ?><span>Preview video</span><?php endif; ?></p><?php if($meta['description']): ?><p class="description"><?=nl2br(h($meta['description']), false)?></p><?php endif; ?><p class="details"><?=h(basename($d))?> · <?=h($info['file_count'] ?? count(list_files($d)))?> files</p></div></article><?php endforeach; ?></div><?=page_links('edit',$editPage,$editPages)?></section><?php endif; ?>
|
||||
<?php if($tab==='edit' && !$editDir): ?><section><h2>Existing input dirs</h2><?php if(!$dirs): ?><p>No input directories yet.</p><?php endif; ?><div class="admin-list video-list"><?php foreach($dirsPage as $d): $runStatus=input_dir_status($d); $running=input_dir_running($d); $enabled=input_dir_enabled($d); $preview=input_dir_preview($d); $state=input_dir_state($d); $fullOutput=basename((string)($state['output'] ?? '')); $previewOutput=basename((string)($state['preview_output'] ?? '')); $hasFullVideo=$fullOutput !== '' && is_file($config['videos_dir'].'/'.$fullOutput); $hasPreviewVideo=$previewOutput !== '' && is_file($config['videos_dir'].'/'.$previewOutput); $displayOutput=($preview && $hasPreviewVideo) ? $previewOutput : ($hasFullVideo ? $fullOutput : ($hasPreviewVideo ? $previewOutput : '')); $hasVideo=$displayOutput !== ''; $displayVideoPath=$hasVideo ? $config['videos_dir'].'/'.$displayOutput : ''; $previewVideo=$hasVideo && $displayOutput === $previewOutput; $canShow=$hasFullVideo && !$preview; $visible=$canShow && input_dir_visible($d); $info=$dirInfo[basename($d)] ?? input_dir_info($d); $data=read_data($d); $meta=cached_video_metadata($displayOutput, $data); ?><article class="video-row admin-video-row<?= $visible ? ' shown' : '' ?>" data-job="<?=h(basename($d))?>"><div><?php if($hasVideo): ?><video controls controlsList="nodownload" oncontextmenu="return false" preload="metadata" src="<?=h($config['public_videos'].'/'.rawurlencode($displayOutput))?>"></video><?php else: ?><div class="video-placeholder"><img src="assets/img/moto_travel.png" alt=""><span>No video yet</span></div><?php endif; ?></div><div class="video-info"><div class="admin-row-top"><div class="admin-switches"><form method="post" class="inline-form"><input type="hidden" name="action" value="set_preview"><input type="hidden" name="dir" value="<?=h(basename($d))?>"><label class="switch-label"><input type="checkbox" name="preview" value="1" <?=$preview?'checked':''?> onchange="this.form.submit()"><span class="switch-ui" aria-hidden="true"></span><span class="switch-text">Preview</span></label></form><form method="post" class="inline-form"><input type="hidden" name="action" value="set_enabled"><input type="hidden" name="dir" value="<?=h(basename($d))?>"><label class="switch-label"><input type="checkbox" name="enabled" value="1" <?=$enabled?'checked':''?> onchange="this.form.submit()"><span class="switch-ui" aria-hidden="true"></span><span class="switch-text">Render</span></label></form><form method="post" class="inline-form"><input type="hidden" name="action" value="set_visible"><input type="hidden" name="dir" value="<?=h(basename($d))?>"><label class="switch-label"><input type="checkbox" name="visible" value="1" <?=$visible?'checked':''?> <?=!$canShow?'disabled':''?> onchange="this.form.submit()"><span class="switch-ui" aria-hidden="true"></span><span class="switch-text">Show</span></label></form><?php if($hasVideo): ?><time class="admin-time" title="Video created at"><?=h(date('d.m.Y H:i', filemtime($displayVideoPath)))?></time><?php endif; ?></div><div class="admin-actions"><?php if($running): ?><span class="button disabled" title="Rendering now" data-edit-action="1">Rendering</span><?php else: ?><a class="button" href="?edit=<?=rawurlencode(basename($d))?>" data-edit-action="1" data-edit-href="?edit=<?=rawurlencode(basename($d))?>">Edit</a><?php endif; ?></div></div><h2><?=h($meta['title'] ?: ($info['title'] ?? basename($d)))?></h2><p class="meta"><?php if($meta['date']): ?><span><?=h($meta['date'])?></span><?php endif; ?><?php if($meta['location']): ?><span><?=h($meta['location'])?></span><?php endif; ?><?php if(!$hasVideo): ?><span>No video</span><?php endif; ?><?php if($previewVideo): ?><span>Preview video</span><?php endif; ?></p><?php if($meta['description']): ?><p class="description"><?=nl2br(h($meta['description']), false)?></p><?php endif; ?><p class="details"><?=h(basename($d))?> · <?=h($info['file_count'] ?? count(list_files($d)))?> files</p></div></article><?php endforeach; ?></div><?=page_links('edit',$editPage,$editPages)?></section><?php endif; ?>
|
||||
<?php if($tab==='edit' && $editDir && $editRunning): ?><section><h2>Edit input dir</h2><p><code>in-dir/<?=h(basename($editDir))?></code></p><div class="err">This input directory is <?=h($editStatus)?>. Editing is disabled until the job completes.</div></section><?php endif; ?>
|
||||
<?php if($tab==='edit' && $editDir && !$editRunning): ?><section><h2>Edit input dir</h2><p><code>in-dir/<?=h(basename($editDir))?></code></p><form method="post" enctype="multipart/form-data" id="edit-form"><input type="hidden" name="action" value="update"><input type="hidden" name="dir" value="<?=h(basename($editDir))?>"><label>Title<input name="title" value="<?=h($editData['title'])?>"></label><label>Date<input name="date" value="<?=h($editData['date'])?>"></label><label>Place<input name="place" value="<?=h($editData['place'])?>"></label><label>Description<textarea name="description" maxlength="5000" data-counter="description-counter-edit"><?=h($editData['description'])?></textarea><small id="description-counter-edit" class="counter"></small></label><label>Add images / videos<input type="file" name="media[]" multiple accept="image/*,video/*"></label><label>Add audio<input type="file" name="audio[]" multiple accept="audio/*"></label><h3>Files and captions</h3><div class="file-list"><?php foreach($editFiles as $f): $ext=strtolower(pathinfo($f, PATHINFO_EXTENSION)); $fileUrl='in-dir/'.rawurlencode(basename($editDir)).'/'.rawurlencode($f); ?><div class="caption-row"><div class="preview"><?php if(in_array($ext,['jpg','jpeg','png','webp','gif'])): ?><img src="<?=h($fileUrl)?>" alt=""><?php elseif(in_array($ext,['mp4','mov','m4v','webm'])): ?><video src="<?=h($fileUrl)?>" muted preload="metadata"></video><?php else: ?><span><?=h(strtoupper($ext ?: 'FILE'))?></span><?php endif; ?></div><div class="caption-fields"><strong><?=h($f)?></strong><?php if(in_array($ext,['jpg','jpeg','png','webp','gif','mp4','mov','m4v','webm'])): ?><input type="hidden" name="caption_files[]" value="<?=h($f)?>"><textarea name="captions[]" placeholder="Optional caption for this file"><?=h($editData['captions'][$f] ?? '')?></textarea><?php if(in_array($ext,['mp4','mov','m4v','webm'])): ?><label class="checkbox-label"><input type="checkbox" name="use_audio_files[]" value="<?=h($f)?>" <?=!empty($editData['video_audio'][$f])?'checked':''?>> <span>Use video file audio</span></label><?php endif; ?><?php else: ?><small>No caption for audio files</small><?php endif; ?></div><button type="button" onclick="deleteFile(<?=h(json_encode($f))?>)">Remove</button></div><?php endforeach; ?></div><button type="submit">Save changes</button></form><form method="post" id="delete-file-form" style="display:none"><input type="hidden" name="action" value="delete_file"><input type="hidden" name="dir" value="<?=h(basename($editDir))?>"><input type="hidden" name="file" id="delete-file-name" value=""></form><form method="post" onsubmit="return confirm(\'Delete this input directory\?\')" id="delete-dir-form""><input type="hidden" name="action" value="delete_dir"><input type="hidden" name="dir" value="<?=h(basename($editDir))?>"><label class="checkbox-label"><input type="checkbox" name="delete_output" value="1"> <span>Also delete generated video, if any</span></label><button class="danger" type="submit">Delete input dir</button></form></section><?php endif; ?>
|
||||
<?php if($tab==='new'): ?><section><h2>Add new movie input</h2><form method="post" enctype="multipart/form-data" id="new-form"><input type="hidden" name="action" value="create"><label>Title*<input name="title" required></label><label>Date<input name="date" placeholder="2026-05-25"></label><label>Place<input name="place"></label><label>Description<textarea name="description" maxlength="5000" data-counter="description-counter-new"></textarea><small id="description-counter-new" class="counter"></small></label><label>Images / videos*<input type="file" name="media[]" multiple required accept="image/*,video/*"></label><label>Audio (optional)<input type="file" name="audio[]" multiple accept="audio/*"></label><button type="submit">Create input-dir</button></form></section><?php endif; ?>
|
||||
|
|
@ -538,50 +551,10 @@ if(editForm){
|
|||
});
|
||||
}
|
||||
document.querySelectorAll('.admin-switches input[type="checkbox"]').forEach(function(input){
|
||||
input.addEventListener('change', async function(event){
|
||||
input.addEventListener('change', function(event){
|
||||
event.preventDefault();
|
||||
const form=input.form;
|
||||
const previous=!input.checked;
|
||||
const row=input.closest('.admin-video-row');
|
||||
const data=new FormData(form);
|
||||
data.set('ajax','1');
|
||||
input.disabled=true;
|
||||
try{
|
||||
const res=await fetch('new.php',{method:'POST',body:data,credentials:'same-origin',headers:{'Accept':'application/json'}});
|
||||
const json=await res.json().catch(function(){return {};});
|
||||
if(!res.ok || !json.ok) throw new Error(json.error || 'Switch update failed');
|
||||
if(data.get('action')==='set_visible' && row){
|
||||
row.classList.toggle('shown', input.checked);
|
||||
}
|
||||
const action=data.get('action');
|
||||
const titleEl=input.closest('.video-info')?.querySelector('h2');
|
||||
const editBtn=row?.querySelector('[data-edit-action="1"]');
|
||||
if(editBtn && (json.running || json.status==='processing' || json.disabled || json.rendering || json.busy || json.ok===true && data.get('action') && data.get('action')!=='set_visible')){
|
||||
if(editBtn.tagName === 'A'){
|
||||
if(!editBtn.dataset.editHref) editBtn.dataset.editHref = editBtn.getAttribute('href') || '';
|
||||
editBtn.removeAttribute('href');
|
||||
editBtn.classList.add('disabled');
|
||||
editBtn.setAttribute('aria-disabled','true');
|
||||
editBtn.title='Rendering now';
|
||||
} else {
|
||||
editBtn.classList.add('disabled');
|
||||
editBtn.title='Rendering now';
|
||||
}
|
||||
}
|
||||
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);
|
||||
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;
|
||||
if(data.get('action')==='set_visible' && row){
|
||||
row.classList.toggle('shown', input.checked);
|
||||
}
|
||||
showToast(e.message || 'Switch update failed', false);
|
||||
}finally{
|
||||
input.disabled=false;
|
||||
}
|
||||
if(form) form.submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue