|
2 | 2 | {% block title %}SecAI OS - Generate{% endblock %} |
3 | 3 | {% block page_title %}Image & Video Generation{% endblock %} |
4 | 4 | {% block content_class %}content-wide{% endblock %} |
| 5 | +{% block extra_css %} |
| 6 | +<style nonce="{{ csp_nonce }}"> |
| 7 | + .generation-result { |
| 8 | + margin-top: 1.5rem; |
| 9 | + text-align: center; |
| 10 | + } |
| 11 | + .generated-media { |
| 12 | + display: block; |
| 13 | + max-width: min(100%, 640px); |
| 14 | + max-height: 60vh; |
| 15 | + width: auto; |
| 16 | + height: auto; |
| 17 | + margin: 0 auto 1rem; |
| 18 | + border-radius: var(--radius-lg); |
| 19 | + object-fit: contain; |
| 20 | + } |
| 21 | +</style> |
| 22 | +{% endblock %} |
5 | 23 |
|
6 | 24 | {% block content %} |
7 | 25 | <div class="tabs"> |
8 | | - <button class="tab active" onclick="switchTab('image', this)">Text to Image</button> |
9 | | - <button class="tab" onclick="switchTab('video', this)">Text to Video</button> |
10 | | - <button class="tab" onclick="switchTab('img2img', this)">Image to Image</button> |
| 26 | + <button class="tab active" type="button" data-tab="image">Text to Image</button> |
| 27 | + <button class="tab" type="button" data-tab="video">Text to Video</button> |
| 28 | + <button class="tab" type="button" data-tab="img2img">Image to Image</button> |
11 | 29 | </div> |
12 | 30 |
|
13 | 31 | <div id="panel-image"> |
|
25 | 43 | <div class="form-group"><label class="form-label">Steps</label><input class="form-input" id="img-steps" type="number" value="30"></div> |
26 | 44 | <div class="form-group"><label class="form-label">Seed</label><input class="form-input" id="img-seed" type="number" placeholder="Random"></div> |
27 | 45 | </div> |
28 | | - <button class="btn btn-primary btn-lg" id="btn-image" onclick="generateImage()">Generate Image</button> |
| 46 | + <button class="btn btn-primary btn-lg" id="btn-image" type="button">Generate Image</button> |
29 | 47 | </div> |
30 | 48 |
|
31 | 49 | <div id="panel-video" class="hidden"> |
|
39 | 57 | <div class="form-group"><label class="form-label">Frames</label><input class="form-input" id="vid-frames" type="number" value="25"></div> |
40 | 58 | <div class="form-group"><label class="form-label">Steps</label><input class="form-input" id="vid-steps" type="number" value="25"></div> |
41 | 59 | </div> |
42 | | - <button class="btn btn-primary btn-lg" id="btn-video" onclick="generateVideo()">Generate Video</button> |
| 60 | + <button class="btn btn-primary btn-lg" id="btn-video" type="button">Generate Video</button> |
43 | 61 | </div> |
44 | 62 |
|
45 | 63 | <div id="panel-img2img" class="hidden"> |
|
55 | 73 | <div class="form-group"><label class="form-label">Strength</label><input class="form-input" id="i2i-strength" type="number" value="0.75" step="0.05" min="0" max="1"></div> |
56 | 74 | <div class="form-group"><label class="form-label">Steps</label><input class="form-input" id="i2i-steps" type="number" value="30"></div> |
57 | 75 | </div> |
58 | | - <button class="btn btn-primary btn-lg" id="btn-img2img" onclick="generateImg2Img()">Generate</button> |
| 76 | + <button class="btn btn-primary btn-lg" id="btn-img2img" type="button">Generate</button> |
59 | 77 | </div> |
60 | 78 |
|
61 | | -<div id="result" style="margin-top:1.5rem;text-align:center"></div> |
| 79 | +<div id="result" class="generation-result"></div> |
62 | 80 | <div id="gen-status" class="hidden" style="margin-top:1rem;padding:1rem;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);font-size:0.85rem;color:var(--text-muted)"></div> |
63 | 81 | {% endblock %} |
64 | 82 |
|
|
99 | 117 | if (data.error) { showGenStatus('Error: ' + data.error); return; } |
100 | 118 | var html = ''; |
101 | 119 | (data.images || []).forEach(function(b64) { |
102 | | - html += '<img src="data:image/png;base64,' + b64 + '" style="max-width:100%;border-radius:var(--radius-lg);margin-bottom:1rem">'; |
| 120 | + html += '<img class="generated-media" src="data:image/png;base64,' + b64 + '" alt="Generated image">'; |
103 | 121 | }); |
104 | 122 | document.getElementById('result').innerHTML = html; |
105 | 123 | showGenStatus('Generated in ' + data.elapsed_seconds + 's'); |
|
126 | 144 | var data = await resp.json(); |
127 | 145 | if (data.error) { showGenStatus('Error: ' + data.error); return; } |
128 | 146 | document.getElementById('result').innerHTML = |
129 | | - '<video controls autoplay style="max-width:100%;border-radius:var(--radius-lg)"><source src="data:video/mp4;base64,' + data.video + '" type="video/mp4"></video>'; |
| 147 | + '<video class="generated-media" controls autoplay><source src="data:video/mp4;base64,' + data.video + '" type="video/mp4"></video>'; |
130 | 148 | showGenStatus('Generated in ' + data.elapsed_seconds + 's'); |
131 | 149 | } catch(e) { showGenStatus('Error: ' + e.message); } |
132 | 150 | finally { btn.disabled = false; } |
|
155 | 173 | var data = await resp.json(); |
156 | 174 | if (data.error) { showGenStatus('Error: ' + data.error); return; } |
157 | 175 | document.getElementById('result').innerHTML = |
158 | | - '<img src="data:image/png;base64,' + data.image + '" style="max-width:100%;border-radius:var(--radius-lg)">'; |
| 176 | + '<img class="generated-media" src="data:image/png;base64,' + data.image + '" alt="Generated image">'; |
159 | 177 | showGenStatus('Generated in ' + data.elapsed_seconds + 's'); |
160 | 178 | } catch(e) { showGenStatus('Error: ' + e.message); } |
161 | 179 | finally { btn.disabled = false; } |
162 | 180 | }; |
163 | 181 | reader.readAsDataURL(file); |
164 | 182 | } |
| 183 | + |
| 184 | + document.querySelectorAll('.tab[data-tab]').forEach(function(button) { |
| 185 | + button.addEventListener('click', function() { |
| 186 | + switchTab(button.getAttribute('data-tab'), button); |
| 187 | + }); |
| 188 | + }); |
| 189 | + document.getElementById('btn-image').addEventListener('click', generateImage); |
| 190 | + document.getElementById('btn-video').addEventListener('click', generateVideo); |
| 191 | + document.getElementById('btn-img2img').addEventListener('click', generateImg2Img); |
165 | 192 | </script> |
166 | 193 | {% endblock %} |
0 commit comments