Add visible file upload label button, inline JS diagnostic badge, update TS event handlers
This commit is contained in:
@@ -156,9 +156,16 @@ el('video-select').addEventListener('change', function () {
|
|||||||
selectedFilePath = this.value;
|
selectedFilePath = this.value;
|
||||||
});
|
});
|
||||||
// ── File upload ───────────────────────────────────────
|
// ── File upload ───────────────────────────────────────
|
||||||
el('video-upload').addEventListener('change', function () {
|
const videoUpload = el('video-upload');
|
||||||
if (this.files?.length)
|
const uploadName = el('upload-name');
|
||||||
|
videoUpload.addEventListener('change', function () {
|
||||||
|
if (this.files?.length) {
|
||||||
selectedFilePath = null; // will upload on submit
|
selectedFilePath = null; // will upload on submit
|
||||||
|
uploadName.textContent = `Selected: ${this.files[0].name} (${formatSize(this.files[0].size)})`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uploadName.textContent = '';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// ── YouTube download ──────────────────────────────────
|
// ── YouTube download ──────────────────────────────────
|
||||||
el('download-url').addEventListener('click', async () => {
|
el('download-url').addEventListener('click', async () => {
|
||||||
@@ -189,10 +196,9 @@ el('download-url').addEventListener('click', async () => {
|
|||||||
el('new-job-form').addEventListener('submit', async (e) => {
|
el('new-job-form').addEventListener('submit', async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!selectedFilePath) {
|
if (!selectedFilePath) {
|
||||||
const fileEl = el('video-upload');
|
if (videoUpload.files?.length) {
|
||||||
if (fileEl.files?.length) {
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('video', fileEl.files[0]);
|
formData.append('video', videoUpload.files[0]);
|
||||||
try {
|
try {
|
||||||
const headers = {};
|
const headers = {};
|
||||||
if (authToken)
|
if (authToken)
|
||||||
@@ -262,7 +268,8 @@ el('new-job-form').addEventListener('submit', async (e) => {
|
|||||||
});
|
});
|
||||||
await apiJson('POST', `/api/jobs/${data.job.id}/start`);
|
await apiJson('POST', `/api/jobs/${data.job.id}/start`);
|
||||||
selectedFilePath = null;
|
selectedFilePath = null;
|
||||||
el('video-upload').value = '';
|
videoUpload.value = '';
|
||||||
|
uploadName.textContent = '';
|
||||||
el('new-job-form').reset();
|
el('new-job-form').reset();
|
||||||
switchTab('dashboard');
|
switchTab('dashboard');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,8 +218,16 @@ el('refresh-files').addEventListener('click', loadBrowseFiles);
|
|||||||
|
|
||||||
// ── File upload ───────────────────────────────────────
|
// ── File upload ───────────────────────────────────────
|
||||||
|
|
||||||
(el('video-upload') as HTMLInputElement).addEventListener('change', function () {
|
const videoUpload = el('video-upload') as HTMLInputElement;
|
||||||
if (this.files?.length) selectedFilePath = null; // will upload on submit
|
const uploadName = el('upload-name');
|
||||||
|
|
||||||
|
videoUpload.addEventListener('change', function () {
|
||||||
|
if (this.files?.length) {
|
||||||
|
selectedFilePath = null; // will upload on submit
|
||||||
|
uploadName.textContent = `Selected: ${this.files[0].name} (${formatSize(this.files[0].size)})`;
|
||||||
|
} else {
|
||||||
|
uploadName.textContent = '';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── YouTube download ──────────────────────────────────
|
// ── YouTube download ──────────────────────────────────
|
||||||
@@ -252,10 +260,9 @@ el('download-url').addEventListener('click', async () => {
|
|||||||
el('new-job-form').addEventListener('submit', async (e) => {
|
el('new-job-form').addEventListener('submit', async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!selectedFilePath) {
|
if (!selectedFilePath) {
|
||||||
const fileEl = el('video-upload') as HTMLInputElement;
|
if (videoUpload.files?.length) {
|
||||||
if (fileEl.files?.length) {
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('video', fileEl.files[0]);
|
formData.append('video', videoUpload.files[0]);
|
||||||
try {
|
try {
|
||||||
const headers: Record<string, string> = {};
|
const headers: Record<string, string> = {};
|
||||||
if (authToken) headers['Authorization'] = `Basic ${authToken}`;
|
if (authToken) headers['Authorization'] = `Basic ${authToken}`;
|
||||||
@@ -321,7 +328,8 @@ el('new-job-form').addEventListener('submit', async (e) => {
|
|||||||
});
|
});
|
||||||
await apiJson('POST', `/api/jobs/${data.job.id}/start`);
|
await apiJson('POST', `/api/jobs/${data.job.id}/start`);
|
||||||
selectedFilePath = null;
|
selectedFilePath = null;
|
||||||
(el('video-upload') as HTMLInputElement).value = '';
|
videoUpload.value = '';
|
||||||
|
uploadName.textContent = '';
|
||||||
(el('new-job-form') as HTMLFormElement).reset();
|
(el('new-job-form') as HTMLFormElement).reset();
|
||||||
switchTab('dashboard');
|
switchTab('dashboard');
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|||||||
@@ -54,7 +54,9 @@
|
|||||||
<button type="button" class="tab-mini" data-src="youtube">YouTube / URL</button>
|
<button type="button" class="tab-mini" data-src="youtube">YouTube / URL</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="src-upload" class="src-panel active">
|
<div id="src-upload" class="src-panel active">
|
||||||
<input type="file" id="video-upload" accept="video/*">
|
<label for="video-upload" class="file-label">Choose a video file...</label>
|
||||||
|
<input type="file" id="video-upload" accept="video/*" style="display:none">
|
||||||
|
<p class="file-name" id="upload-name"></p>
|
||||||
</div>
|
</div>
|
||||||
<div id="src-browse" class="src-panel">
|
<div id="src-browse" class="src-panel">
|
||||||
<select id="video-select"><option value="">-- Select file --</option></select>
|
<select id="video-select"><option value="">-- Select file --</option></select>
|
||||||
@@ -140,6 +142,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
console.log('INLINE: page loaded, about to load app.js');
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var diag = document.createElement('div');
|
||||||
|
diag.id = 'js-diag';
|
||||||
|
diag.style.cssText = 'position:fixed;top:0;right:0;background:#238636;color:#fff;padding:2px 8px;font-size:11px;z-index:9999;border-radius:0 0 0 4px';
|
||||||
|
diag.textContent = 'JS ✓';
|
||||||
|
document.body.appendChild(diag);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<script defer src="/app.js"></script>
|
<script defer src="/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ details .form-grid { margin-top: 12px; }
|
|||||||
.hint { color: #8b949e; font-size: 0.85rem; margin-top: -12px; margin-bottom: 16px; }
|
.hint { color: #8b949e; font-size: 0.85rem; margin-top: -12px; margin-bottom: 16px; }
|
||||||
|
|
||||||
select, input[type="file"], input[type="url"] { padding: 8px 12px; background: #0d1117; border: 1px solid #30363d; border-radius: 6px; color: #c9d1d9; font-size: 0.9rem; }
|
select, input[type="file"], input[type="url"] { padding: 8px 12px; background: #0d1117; border: 1px solid #30363d; border-radius: 6px; color: #c9d1d9; font-size: 0.9rem; }
|
||||||
|
.file-label { display: inline-block; padding: 10px 20px; background: #238636; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.95rem; }
|
||||||
|
.file-label:hover { background: #2ea043; }
|
||||||
|
.file-name { margin: 8px 0 0; font-size: 0.85rem; color: #8b949e; }
|
||||||
|
|
||||||
/* Job cards */
|
/* Job cards */
|
||||||
.jobs-list { display: flex; flex-direction: column; gap: 8px; }
|
.jobs-list { display: flex; flex-direction: column; gap: 8px; }
|
||||||
|
|||||||
Reference in New Issue
Block a user