Spaces:
Running
Running
Commit ·
fef9384
1
Parent(s): df89645
fix dangling js, refine onedrive styling and add persistence
Browse files- templates/index.html +61 -25
templates/index.html
CHANGED
|
@@ -4,11 +4,11 @@
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
-
<title>
|
| 8 |
<link rel="icon"
|
| 9 |
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 512 512%22><path fill=%22%2320f3b4%22 d=%22M448 32H64C28.7 32 0 60.7 0 96v320c0 35.3 28.7 64 64 64h384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64zm-52.2 64l-32 64H271.8l32-64h92zm-144 0l-32 64H127.8l32-64h92zM64 96h19.8l-32 64H64V96zm384 320H64V192h384v224z%22/></svg>">
|
| 10 |
<link
|
| 11 |
-
href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;500;800&family=
|
| 12 |
rel="stylesheet">
|
| 13 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
| 14 |
<style>
|
|
@@ -24,7 +24,7 @@
|
|
| 24 |
--text-main: #e2e8f0;
|
| 25 |
--text-dim: #94a3b8;
|
| 26 |
--font-sans: 'Plus Jakarta Sans', sans-serif;
|
| 27 |
-
--font-mono: '
|
| 28 |
--success-color: #00ff9d;
|
| 29 |
--error-color: #ff4d4d;
|
| 30 |
}
|
|
@@ -636,7 +636,7 @@
|
|
| 636 |
</button>
|
| 637 |
|
| 638 |
<div id="onedrive-instruction"
|
| 639 |
-
style="font-size: 0.
|
| 640 |
</div>
|
| 641 |
|
| 642 |
<div id="onedrive-status"
|
|
@@ -659,7 +659,7 @@
|
|
| 659 |
<!-- CENTER: Creative Studio -->
|
| 660 |
<div class="glass-panel creative-studio">
|
| 661 |
<div class="prism-refraction"></div>
|
| 662 |
-
<h2 class="section-label"><span></span>
|
| 663 |
<textarea id="style_desc" name="style_desc" class="text-console" required
|
| 664 |
placeholder="Describe the desired cinematic flow...">{{ default_style_desc | escape }}</textarea>
|
| 665 |
<div class="quick-presets">
|
|
@@ -681,19 +681,19 @@
|
|
| 681 |
<h2 class="section-label"><span></span> Command</h2>
|
| 682 |
|
| 683 |
<div class="control-group">
|
| 684 |
-
<label>TARGET DURATION
|
| 685 |
<input type="number" id="duration" name="duration" class="control-input" value="30" min="1">
|
| 686 |
</div>
|
| 687 |
|
| 688 |
<div class="control-group">
|
| 689 |
-
<label>
|
| 690 |
<select id="model_name" name="model_name" class="control-input">
|
| 691 |
<option value="gemini-3-flash-preview">Initializing...</option>
|
| 692 |
</select>
|
| 693 |
</div>
|
| 694 |
|
| 695 |
<div class="toggle-switch" onclick="document.getElementById('mute_audio').click()">
|
| 696 |
-
<span style="font-size: 0.65rem; font-weight: 600; font-family: var(--font-mono);">MUTE
|
| 697 |
AUDIO</span>
|
| 698 |
<label class="custom-switch" onclick="event.stopPropagation()">
|
| 699 |
<input type="checkbox" id="mute_audio" name="mute_audio" checked>
|
|
@@ -710,9 +710,9 @@
|
|
| 710 |
</div>
|
| 711 |
|
| 712 |
<div class="glass-panel pulse-feed">
|
| 713 |
-
<h2 class="section-label"><span></span>
|
| 714 |
<div class="thinking-logs" id="thinking-header">
|
| 715 |
-
>
|
| 716 |
</div>
|
| 717 |
<div id="progress-area" style="display: none; margin-top: auto;">
|
| 718 |
<div id="progress-message"
|
|
@@ -810,7 +810,7 @@
|
|
| 810 |
});
|
| 811 |
}
|
| 812 |
} catch (error) {
|
| 813 |
-
modelSelect.innerHTML = '<option value="gemini-3-flash-preview">
|
| 814 |
}
|
| 815 |
}
|
| 816 |
loadModels();
|
|
@@ -953,10 +953,13 @@
|
|
| 953 |
|
| 954 |
if (data.status === 'success') {
|
| 955 |
instructionOnedrive.style.display = 'block';
|
|
|
|
| 956 |
instructionOnedrive.innerHTML = `
|
| 957 |
-
<
|
| 958 |
-
1. Visit <a href="https://www.microsoft.com/link" target="_blank">microsoft.com/link</a><
|
| 959 |
-
2.
|
|
|
|
|
|
|
| 960 |
`;
|
| 961 |
|
| 962 |
const poll = setInterval(async () => {
|
|
@@ -965,6 +968,7 @@
|
|
| 965 |
if (sData.status === 'success') {
|
| 966 |
clearInterval(poll);
|
| 967 |
document.getElementById('onedrive_access_token').value = sData.access_token;
|
|
|
|
| 968 |
instructionOnedrive.style.display = 'none';
|
| 969 |
btnOnedrive.style.display = 'none';
|
| 970 |
statusOnedrive.style.display = 'block';
|
|
@@ -976,23 +980,55 @@
|
|
| 976 |
}
|
| 977 |
} catch (err) {
|
| 978 |
btnOnedrive.disabled = false;
|
| 979 |
-
btnOnedrive.
|
| 980 |
}
|
| 981 |
});
|
| 982 |
|
| 983 |
async function fetchOneDriveProjects(token) {
|
| 984 |
-
projectListOnedrive.innerHTML = '<div style="padding: 10px; font-size: 0.7rem;">Fetching...</div>';
|
| 985 |
-
|
| 986 |
-
|
| 987 |
-
|
| 988 |
-
|
| 989 |
-
|
| 990 |
-
|
| 991 |
-
|
| 992 |
-
|
| 993 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 994 |
}
|
| 995 |
}
|
|
|
|
| 996 |
|
| 997 |
function renderProjects(list) {
|
| 998 |
projectListOnedrive.innerHTML = '';
|
|
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>Auto Video Editor</title>
|
| 8 |
<link rel="icon"
|
| 9 |
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 512 512%22><path fill=%22%2320f3b4%22 d=%22M448 32H64C28.7 32 0 60.7 0 96v320c0 35.3 28.7 64 64 64h384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64zm-52.2 64l-32 64H271.8l32-64h92zm-144 0l-32 64H127.8l32-64h92zM64 96h19.8l-32 64H64V96zm384 320H64V192h384v224z%22/></svg>">
|
| 10 |
<link
|
| 11 |
+
href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;500;800&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap"
|
| 12 |
rel="stylesheet">
|
| 13 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
| 14 |
<style>
|
|
|
|
| 24 |
--text-main: #e2e8f0;
|
| 25 |
--text-dim: #94a3b8;
|
| 26 |
--font-sans: 'Plus Jakarta Sans', sans-serif;
|
| 27 |
+
--font-mono: 'Work Sans', monospace;
|
| 28 |
--success-color: #00ff9d;
|
| 29 |
--error-color: #ff4d4d;
|
| 30 |
}
|
|
|
|
| 636 |
</button>
|
| 637 |
|
| 638 |
<div id="onedrive-instruction"
|
| 639 |
+
style="font-size: 0.85rem; padding: 15px; border: 1px solid var(--glass-border); border-radius: 12px; margin-bottom: 10px; display: none; background: rgba(0,0,0,0.2);">
|
| 640 |
</div>
|
| 641 |
|
| 642 |
<div id="onedrive-status"
|
|
|
|
| 659 |
<!-- CENTER: Creative Studio -->
|
| 660 |
<div class="glass-panel creative-studio">
|
| 661 |
<div class="prism-refraction"></div>
|
| 662 |
+
<h2 class="section-label"><span></span>AI Prompt</h2>
|
| 663 |
<textarea id="style_desc" name="style_desc" class="text-console" required
|
| 664 |
placeholder="Describe the desired cinematic flow...">{{ default_style_desc | escape }}</textarea>
|
| 665 |
<div class="quick-presets">
|
|
|
|
| 681 |
<h2 class="section-label"><span></span> Command</h2>
|
| 682 |
|
| 683 |
<div class="control-group">
|
| 684 |
+
<label>TARGET DURATION</label>
|
| 685 |
<input type="number" id="duration" name="duration" class="control-input" value="30" min="1">
|
| 686 |
</div>
|
| 687 |
|
| 688 |
<div class="control-group">
|
| 689 |
+
<label>LLM MODEL</label>
|
| 690 |
<select id="model_name" name="model_name" class="control-input">
|
| 691 |
<option value="gemini-3-flash-preview">Initializing...</option>
|
| 692 |
</select>
|
| 693 |
</div>
|
| 694 |
|
| 695 |
<div class="toggle-switch" onclick="document.getElementById('mute_audio').click()">
|
| 696 |
+
<span style="font-size: 0.65rem; font-weight: 600; font-family: var(--font-mono);">MUTE
|
| 697 |
AUDIO</span>
|
| 698 |
<label class="custom-switch" onclick="event.stopPropagation()">
|
| 699 |
<input type="checkbox" id="mute_audio" name="mute_audio" checked>
|
|
|
|
| 710 |
</div>
|
| 711 |
|
| 712 |
<div class="glass-panel pulse-feed">
|
| 713 |
+
<h2 class="section-label"><span></span> Live-Feed</h2>
|
| 714 |
<div class="thinking-logs" id="thinking-header">
|
| 715 |
+
> Waiting for your input...
|
| 716 |
</div>
|
| 717 |
<div id="progress-area" style="display: none; margin-top: auto;">
|
| 718 |
<div id="progress-message"
|
|
|
|
| 810 |
});
|
| 811 |
}
|
| 812 |
} catch (error) {
|
| 813 |
+
modelSelect.innerHTML = '<option value="gemini-3-flash-preview">Gemini 3 Flash Preview</option>';
|
| 814 |
}
|
| 815 |
}
|
| 816 |
loadModels();
|
|
|
|
| 953 |
|
| 954 |
if (data.status === 'success') {
|
| 955 |
instructionOnedrive.style.display = 'block';
|
| 956 |
+
btnOnedrive.style.display = 'none';
|
| 957 |
instructionOnedrive.innerHTML = `
|
| 958 |
+
<div style="margin-bottom: 12px; color: var(--chlorophyll); font-weight: 800; letter-spacing: 1px;"><i class="fas fa-lock"></i> SIGN-IN REQUIRED</div>
|
| 959 |
+
<div style="margin-bottom: 8px;">1. Visit <a href="https://www.microsoft.com/link" target="_blank" style="font-size: 0.95rem;">microsoft.com/link</a></div>
|
| 960 |
+
<div>2. Enter code:<br>
|
| 961 |
+
<b style="font-size: 1.6rem; letter-spacing: 3px; color: var(--chlorophyll); background: rgba(0,0,0,0.4); padding: 8px 16px; border-radius: 8px; display: inline-block; margin-top: 8px; user-select: text;">${data.user_code}</b>
|
| 962 |
+
</div>
|
| 963 |
`;
|
| 964 |
|
| 965 |
const poll = setInterval(async () => {
|
|
|
|
| 968 |
if (sData.status === 'success') {
|
| 969 |
clearInterval(poll);
|
| 970 |
document.getElementById('onedrive_access_token').value = sData.access_token;
|
| 971 |
+
localStorage.setItem('velocity_onedrive_token', sData.access_token);
|
| 972 |
instructionOnedrive.style.display = 'none';
|
| 973 |
btnOnedrive.style.display = 'none';
|
| 974 |
statusOnedrive.style.display = 'block';
|
|
|
|
| 980 |
}
|
| 981 |
} catch (err) {
|
| 982 |
btnOnedrive.disabled = false;
|
| 983 |
+
btnOnedrive.innerHTML = '<i class="fab fa-microsoft"></i> Retry Link';
|
| 984 |
}
|
| 985 |
});
|
| 986 |
|
| 987 |
async function fetchOneDriveProjects(token) {
|
| 988 |
+
projectListOnedrive.innerHTML = '<div style="padding: 10px; font-size: 0.7rem; color: var(--text-dim);"><i class="fas fa-spinner fa-spin"></i> Fetching Cloud Projects...</div>';
|
| 989 |
+
try {
|
| 990 |
+
const res = await fetch('/api/onedrive/projects', {
|
| 991 |
+
method: 'POST',
|
| 992 |
+
headers: { 'Content-Type': 'application/json' },
|
| 993 |
+
body: JSON.stringify({ access_token: token })
|
| 994 |
+
});
|
| 995 |
+
const data = await res.json();
|
| 996 |
+
if (data.status === 'success') {
|
| 997 |
+
onedriveProjects = data.projects;
|
| 998 |
+
renderProjects(onedriveProjects);
|
| 999 |
+
} else {
|
| 1000 |
+
// Token expired or invalid
|
| 1001 |
+
resetOneDriveLogin();
|
| 1002 |
+
}
|
| 1003 |
+
} catch (e) {
|
| 1004 |
+
resetOneDriveLogin();
|
| 1005 |
+
}
|
| 1006 |
+
}
|
| 1007 |
+
|
| 1008 |
+
function resetOneDriveLogin() {
|
| 1009 |
+
localStorage.removeItem('velocity_onedrive_token');
|
| 1010 |
+
btnOnedrive.style.display = 'block';
|
| 1011 |
+
btnOnedrive.innerHTML = '<i class="fab fa-microsoft"></i> Connect OneDrive';
|
| 1012 |
+
btnOnedrive.disabled = false;
|
| 1013 |
+
statusOnedrive.style.display = 'none';
|
| 1014 |
+
projectSelectionOnedrive.style.display = 'none';
|
| 1015 |
+
projectListOnedrive.innerHTML = '';
|
| 1016 |
+
}
|
| 1017 |
+
|
| 1018 |
+
async function initOneDriveCache() {
|
| 1019 |
+
const cachedToken = localStorage.getItem('velocity_onedrive_token');
|
| 1020 |
+
if (cachedToken) {
|
| 1021 |
+
btnOnedrive.style.display = 'none';
|
| 1022 |
+
statusOnedrive.style.display = 'block';
|
| 1023 |
+
statusOnedrive.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Restoring Cloud Link...';
|
| 1024 |
+
document.getElementById('onedrive_access_token').value = cachedToken;
|
| 1025 |
+
projectSelectionOnedrive.style.display = 'block';
|
| 1026 |
+
fetchOneDriveProjects(cachedToken).then(() => {
|
| 1027 |
+
statusOnedrive.innerHTML = '<i class="fas fa-check-circle"></i> Linked to OneDrive';
|
| 1028 |
+
});
|
| 1029 |
}
|
| 1030 |
}
|
| 1031 |
+
initOneDriveCache();
|
| 1032 |
|
| 1033 |
function renderProjects(list) {
|
| 1034 |
projectListOnedrive.innerHTML = '';
|