Skip to content

Commit 817167e

Browse files
author
vector17002
committed
added transcoding services and workers
1 parent d5283c6 commit 817167e

2 files changed

Lines changed: 54 additions & 27 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ dist/
66
.DS_Store
77
coverage/
88
*.log
9+
downloads/

web/index.html

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<!DOCTYPE html>
22
<html lang="en">
3+
34
<head>
45
<meta charset="UTF-8">
56
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -165,7 +166,7 @@
165166
color: var(--text-muted);
166167
font-size: 0.8rem;
167168
}
168-
169+
169170
#selected-file-name {
170171
display: block;
171172
margin-top: 1rem;
@@ -206,7 +207,7 @@
206207
color: var(--success-color);
207208
border: 1px solid rgba(16, 185, 129, 0.2);
208209
}
209-
210+
210211
.progress-bar {
211212
width: 100%;
212213
height: 6px;
@@ -216,7 +217,7 @@
216217
overflow: hidden;
217218
display: none;
218219
}
219-
220+
220221
.progress-fill {
221222
height: 100%;
222223
background: var(--primary-color);
@@ -228,7 +229,7 @@
228229
display: inline-block;
229230
width: 1.25rem;
230231
height: 1.25rem;
231-
border: 2px solid rgba(255,255,255,0.3);
232+
border: 2px solid rgba(255, 255, 255, 0.3);
232233
border-radius: 50%;
233234
border-top-color: white;
234235
animation: spin 1s ease-in-out infinite;
@@ -238,11 +239,11 @@
238239
transform: translate(-50%, -50%);
239240
display: none;
240241
}
241-
242+
242243
.btn.loading {
243244
color: transparent;
244245
}
245-
246+
246247
.btn.loading .loader {
247248
display: block;
248249
}
@@ -264,12 +265,15 @@
264265
}
265266

266267
@keyframes spin {
267-
to { transform: translate(-50%, -50%) rotate(360deg); }
268+
to {
269+
transform: translate(-50%, -50%) rotate(360deg);
270+
}
268271
}
269272
</style>
270273
<!-- Importing Inter Font -->
271274
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
272275
</head>
276+
273277
<body>
274278

275279
<!-- Authentication View -->
@@ -278,7 +282,7 @@
278282
<h1 id="auth-title">Welcome Back</h1>
279283
<p id="auth-subtitle">Sign in to upload files</p>
280284
</div>
281-
285+
282286
<form id="auth-form">
283287
<div class="form-group">
284288
<label for="email">Email Address</label>
@@ -304,11 +308,12 @@ <h1 id="auth-title">Welcome Back</h1>
304308
<h1>Upload File</h1>
305309
<p>Secure direct upload to S3</p>
306310
</div>
307-
311+
308312
<div class="file-upload-wrapper" id="drop-zone">
309313
<input type="file" id="file-input" required>
310314
<div class="file-upload-icon">
311-
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
315+
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
316+
stroke-linecap="round" stroke-linejoin="round">
312317
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
313318
<polyline points="17 8 12 3 7 8"></polyline>
314319
<line x1="12" y1="3" x2="12" y2="15"></line>
@@ -323,17 +328,21 @@ <h1>Upload File</h1>
323328
<span>Start Upload</span>
324329
<div class="loader"></div>
325330
</button>
326-
331+
327332
<div class="progress-bar" id="progress-container">
328333
<div class="progress-fill" id="progress-bar"></div>
329334
</div>
330335

331336
<div id="upload-status" class="status-message"></div>
337+
338+
<button type="button" class="btn" id="logout-btn" style="background: var(--surface-color); color: var(--text-muted); border: 1px solid var(--border-color); margin-top: 1rem;">
339+
Logout
340+
</button>
332341
</div>
333342

334343
<script>
335344
const API_BASE = 'http://localhost:8080/api';
336-
345+
337346
// DOM Elements
338347
const authView = document.getElementById('auth-view');
339348
const uploadView = document.getElementById('upload-view');
@@ -346,9 +355,9 @@ <h1>Upload File</h1>
346355
const toggleAuthBtn = document.getElementById('toggle-auth');
347356
const authTitle = document.getElementById('auth-title');
348357
const authSubtitle = document.getElementById('auth-subtitle');
349-
358+
350359
let isLoginMode = true;
351-
360+
352361
const fileInput = document.getElementById('file-input');
353362
const dropZone = document.getElementById('drop-zone');
354363
const fileNameDisplay = document.getElementById('selected-file-name');
@@ -379,7 +388,7 @@ <h1>Upload File</h1>
379388
uploadView.classList.remove('hidden');
380389
}
381390
};
382-
391+
383392
// Check initially
384393
checkAuth();
385394

@@ -426,9 +435,9 @@ <h1>Upload File</h1>
426435
// Both login and register return { user, token }
427436
document.cookie = `token=${data.token}; path=/; max-age=3600`;
428437
localStorage.setItem('token', data.token);
429-
438+
430439
showStatus(authStatus, isLoginMode ? 'Login successful!' : 'Registration successful!', false);
431-
440+
432441
setTimeout(() => {
433442
authView.classList.add('hidden');
434443
uploadView.classList.remove('hidden');
@@ -496,7 +505,7 @@ <h1>Upload File</h1>
496505
// 1. Get Presigned URL
497506
const urlResponse = await fetch(`${API_BASE}/s3/upload`, {
498507
method: 'POST',
499-
headers: {
508+
headers: {
500509
'Content-Type': 'application/json',
501510
'Authorization': `Bearer ${localStorage.getItem('token') || ''}`
502511
},
@@ -526,25 +535,25 @@ <h1>Upload File</h1>
526535
await new Promise((resolve, reject) => {
527536
progressContainer.style.display = 'block';
528537
const xhr = new XMLHttpRequest();
529-
538+
530539
xhr.upload.addEventListener("progress", (event) => {
531540
if (event.lengthComputable) {
532541
const percentComplete = (event.loaded / event.total) * 100;
533542
progressBar.style.width = percentComplete + '%';
534543
}
535544
});
536-
545+
537546
xhr.addEventListener("load", () => {
538547
if (xhr.status >= 200 && xhr.status < 300) {
539548
resolve(xhr.status);
540549
} else {
541550
reject(new Error(`S3 responded with status ${xhr.status}`));
542551
}
543552
});
544-
553+
545554
xhr.addEventListener("error", () => reject(new Error("Network error during upload")));
546555
xhr.addEventListener("abort", () => reject(new Error("Upload aborted")));
547-
556+
548557
xhr.open("PUT", url, true);
549558
xhr.setRequestHeader("Content-Type", selectedFile.type || 'application/octet-stream');
550559
xhr.send(selectedFile);
@@ -554,24 +563,24 @@ <h1>Upload File</h1>
554563
try {
555564
await fetch(`${API_BASE}/s3/process`, {
556565
method: 'POST',
557-
headers: {
566+
headers: {
558567
'Content-Type': 'application/json',
559568
'Authorization': `Bearer ${localStorage.getItem('token') || ''}`
560569
},
561570
credentials: 'include',
562571
body: JSON.stringify({ fileId })
563572
});
564-
} catch(e) {
573+
} catch (e) {
565574
console.error("Failed to notify backend for processing", e);
566575
}
567576

568577
showStatus(uploadStatus, `Upload successful & processing started! File ID: ${fileId}`, false);
569-
578+
570579
// Reset file selection
571580
selectedFile = null;
572581
fileInput.value = '';
573582
fileNameDisplay.textContent = '';
574-
583+
575584
} catch (error) {
576585
if (error.message !== 'Unauthorized') {
577586
showStatus(uploadStatus, error.message, true);
@@ -583,6 +592,23 @@ <h1>Upload File</h1>
583592
fileInput.disabled = false;
584593
}
585594
});
595+
596+
// Handle Logout
597+
const logoutBtn = document.getElementById('logout-btn');
598+
if (logoutBtn) {
599+
logoutBtn.addEventListener('click', () => {
600+
document.cookie = 'token=; Max-Age=0; path=/;';
601+
localStorage.removeItem('token');
602+
uploadView.classList.add('hidden');
603+
authView.classList.remove('hidden');
604+
// Clear inputs
605+
emailInput.value = '';
606+
passwordInput.value = '';
607+
hideStatus(authStatus);
608+
hideStatus(uploadStatus);
609+
});
610+
}
586611
</script>
587612
</body>
588-
</html>
613+
614+
</html>

0 commit comments

Comments
 (0)