ruv commited on
Commit
74aac0f
·
verified ·
1 Parent(s): e35dcc0

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +172 -13
templates/index.html CHANGED
@@ -1,14 +1,4 @@
1
-
2
  <!DOCTYPE html>
3
- <!--
4
- _____ .__ ____ ___.__ .___
5
- / _ \ |__| \ \ / |__| __| _/____ ____
6
- / /_\ \| | \ Y /| |/ __ _/ __ \/ _ \
7
- / | | | \ / | / /_/ \ ___( <_> )
8
- \____|__ |__| \___/ |__\____ |\___ \____/
9
- \/ \/ \/
10
- created by rUv
11
- -->
12
  <html lang="en">
13
  <head>
14
  <meta charset="UTF-8">
@@ -92,7 +82,6 @@
92
  <button id="stopCapture" class="btn btn-danger">🛑 Stop Capture</button>
93
  <button id="toggleSettings" class="btn btn-info">⚙️ Settings</button>
94
  </div>
95
-
96
  </div>
97
  <div class="settings-panel card card-body">
98
  <ul class="nav nav-tabs" id="settingsTabs" role="tablist">
@@ -114,7 +103,8 @@
114
  <input type="number" id="refreshRate" class="form-control" placeholder="Refresh rate in seconds" value="15">
115
  </div>
116
  <div class="tab-pane fade" id="api" role="tabpanel" aria-labelledby="api-tab">
117
- <input type="text" id="apiKey" class="form-control" placeholder="OpenAI API Key" value="">
 
118
  </div>
119
  <button id="saveSettings" class="btn btn-success mt-3">Save Settings</button>
120
  </div>
@@ -129,5 +119,174 @@
129
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
130
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
131
  <script src="/static/script.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  </body>
133
- </html>
 
 
1
  <!DOCTYPE html>
 
 
 
 
 
 
 
 
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
 
82
  <button id="stopCapture" class="btn btn-danger">🛑 Stop Capture</button>
83
  <button id="toggleSettings" class="btn btn-info">⚙️ Settings</button>
84
  </div>
 
85
  </div>
86
  <div class="settings-panel card card-body">
87
  <ul class="nav nav-tabs" id="settingsTabs" role="tablist">
 
103
  <input type="number" id="refreshRate" class="form-control" placeholder="Refresh rate in seconds" value="15">
104
  </div>
105
  <div class="tab-pane fade" id="api" role="tabpanel" aria-labelledby="api-tab">
106
+ <input type="password" id="apiKey" class="form-control" placeholder="OpenAI API Key">
107
+ <input type="checkbox" id="showApiKey"> Show API Key
108
  </div>
109
  <button id="saveSettings" class="btn btn-success mt-3">Save Settings</button>
110
  </div>
 
119
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
120
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
121
  <script src="/static/script.js"></script>
122
+ <script>
123
+ const video = document.getElementById('video');
124
+ const formattedMarkdownDiv = document.getElementById('formattedMarkdown');
125
+ const toggleSettingsButton = document.getElementById('toggleSettings');
126
+ const settingsPanel = document.querySelector('.settings-panel');
127
+ const saveSettingsButton = document.getElementById('saveSettings');
128
+ const startCaptureButton = document.getElementById('startCapture');
129
+ const stopCaptureButton = document.getElementById('stopCapture');
130
+ const showApiKeyCheckbox = document.getElementById('showApiKey');
131
+ const apiKeyInput = document.getElementById('apiKey');
132
+ let captureInterval;
133
+ let refreshRate = 15;
134
+ let customPrompt = "Analyze this frame";
135
+ let apiKey = "";
136
+ let activeStream = null;
137
+ let isProcessing = false; // Flag to track if processing is in progress
138
+
139
+ function logMessage(message) {
140
+ const p = document.createElement('p');
141
+ p.textContent = message;
142
+ formattedMarkdownDiv.appendChild(p);
143
+ formattedMarkdownDiv.scrollTop = formattedMarkdownDiv.scrollHeight; // Scroll to bottom
144
+ }
145
+
146
+ async function startWebcamStream() {
147
+ activeStream = await navigator.mediaDevices.getUserMedia({ video: true });
148
+ logMessage("Webcam stream started.");
149
+ video.srcObject = activeStream;
150
+ }
151
+
152
+ async function startScreenShare() {
153
+ activeStream = await navigator.mediaDevices.getDisplayMedia({ video: true });
154
+ logMessage("Screen share started.");
155
+ video.srcObject = activeStream;
156
+ }
157
+
158
+ async function startApplicationShare() {
159
+ activeStream = await navigator.mediaDevices.getDisplayMedia({
160
+ video: {
161
+ cursor: "always",
162
+ displaySurface: "application"
163
+ }
164
+ });
165
+ logMessage("Application share started.");
166
+ video.srcObject = activeStream;
167
+ }
168
+
169
+ async function handleStreamSelection(event) {
170
+ if (isProcessing) {
171
+ event.stopImmediatePropagation(); // Stop event propagation immediately
172
+ return; // Terminate the function
173
+ }
174
+ isProcessing = true; // Set the flag to indicate processing is in progress
175
+
176
+ // Remove active class from all buttons
177
+ document.querySelectorAll('.btn-group-toggle .btn').forEach(btn => btn.classList.remove('active'));
178
+
179
+ // Add active class to the clicked button
180
+ event.target.closest('.btn').classList.add('active');
181
+
182
+ const selectedButton = event.target.closest('.btn').querySelector('input');
183
+ if (!selectedButton) {
184
+ console.error('No input element found inside the clicked button.');
185
+ isProcessing = false; // Reset the flag
186
+ return;
187
+ }
188
+
189
+ const selectedButtonId = selectedButton.id;
190
+ if (activeStream) {
191
+ // Stop the previous stream
192
+ let tracks = activeStream.getTracks();
193
+ tracks.forEach(track => track.stop());
194
+ activeStream = null;
195
+ }
196
+
197
+ if (selectedButtonId === 'shareWebcam') {
198
+ await startWebcamStream();
199
+ } else if (selectedButtonId === 'shareScreen') {
200
+ await startScreenShare();
201
+ } else if (selectedButtonId === 'shareApplication') {
202
+ await startApplicationShare();
203
+ }
204
+
205
+ isProcessing = false; // Reset the flag after processing is complete
206
+ }
207
+
208
+ // Event delegation for stream selection buttons
209
+ document.body.addEventListener('click', (event) => {
210
+ if (event.target.closest('.btn-group-toggle .btn')) {
211
+ handleStreamSelection(event);
212
+ }
213
+ });
214
+
215
+ // Toggle settings panel
216
+ toggleSettingsButton.addEventListener('click', () => {
217
+ settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
218
+ logMessage("");
219
+ });
220
+
221
+ // Save settings
222
+ saveSettingsButton.addEventListener('click', () => {
223
+ customPrompt = document.getElementById('customPrompt').value || "Analyze this frame";
224
+ refreshRate = document.getElementById('refreshRate').value || 15;
225
+ apiKey = document.getElementById('apiKey').value || "";
226
+ settingsPanel.style.display = 'none';
227
+ logMessage("Settings saved.");
228
+ });
229
+
230
+ // Show/Hide API Key
231
+ showApiKeyCheckbox.addEventListener('change', () => {
232
+ apiKeyInput.type = showApiKeyCheckbox.checked ? 'text' : 'password';
233
+ });
234
+
235
+ // Start Capture
236
+ startCaptureButton.addEventListener('click', () => {
237
+ if (isProcessing || captureInterval) {
238
+ return; // Terminate if processing is in progress or capture is already running
239
+ }
240
+ isProcessing = true; // Set the flag to indicate processing is in progress
241
+
242
+ captureFrame(); // Capture the first frame immediately
243
+ captureInterval = setInterval(captureFrame, refreshRate * 1000); // Capture every `refreshRate` seconds
244
+ logMessage("Capture started.");
245
+
246
+ isProcessing = false; // Reset the flag after processing is complete
247
+ });
248
+
249
+ // Stop Capture
250
+ stopCaptureButton.addEventListener('click', () => {
251
+ if (isProcessing || !captureInterval) {
252
+ return; // Terminate if processing is in progress or capture is not running
253
+ }
254
+ isProcessing = true; // Set the flag to indicate processing is in progress
255
+
256
+ clearInterval(captureInterval);
257
+ captureInterval = null;
258
+ logMessage("Capture stopped.");
259
+
260
+ isProcessing = false; // Reset the flag after processing is complete
261
+ });
262
+
263
+ function captureFrame() {
264
+ const canvas = document.createElement('canvas');
265
+ canvas.width = video.videoWidth;
266
+ canvas.height = video.videoHeight;
267
+ const context = canvas.getContext('2d');
268
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
269
+ const dataUrl = canvas.toDataURL('image/jpeg');
270
+
271
+ logMessage("Frame captured and sent to API.");
272
+ fetch('/process_frame', {
273
+ method: 'POST',
274
+ headers: {
275
+ 'Content-Type': 'application/json'
276
+ },
277
+ body: JSON.stringify({ image: dataUrl, prompt: customPrompt, api_key: apiKey })
278
+ })
279
+ .then(response => response.json())
280
+ .then(data => {
281
+ const formattedMarkdown = marked.parse(data.response); // Fixed function call
282
+ formattedMarkdownDiv.innerHTML = formattedMarkdown;
283
+ formattedMarkdownDiv.scrollTop = formattedMarkdownDiv.scrollHeight; // Scroll to bottom
284
+ })
285
+ .catch(error => {
286
+ console.error('Error:', error);
287
+ logMessage(`Error: ${error.message}`);
288
+ });
289
+ }
290
+ </script>
291
  </body>
292
+ </html>