Escapingmatrixtoday commited on
Commit
d65c541
·
verified ·
1 Parent(s): d527267

There's still malfunctions. Check the entire system, button and all functions and fix it successfully

Browse files
Files changed (1) hide show
  1. index.html +127 -62
index.html CHANGED
@@ -225,40 +225,49 @@
225
  </div>
226
 
227
  <script>
228
- // Initialize Vanta.js background
229
- VANTA.GLOBE({
230
- el: "#vanta-bg",
231
- mouseControls: true,
232
- touchControls: true,
233
- gyroControls: false,
234
- minHeight: 200.00,
235
- minWidth: 200.00,
236
- scale: 1.00,
237
- scaleMobile: 1.00,
238
- color: 0x6366f1,
239
- backgroundColor: 0xffffff,
240
- size: 0.8
241
- });
242
-
243
- // Initialize feather icons
 
 
 
 
244
  feather.replace();
245
-
246
  // Tab switching functionality
247
  const youtubeTab = document.getElementById('youtube-tab');
248
  const tiktokTab = document.getElementById('tiktok-tab');
249
 
250
- youtubeTab.addEventListener('click', () => {
251
  youtubeTab.classList.add('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
252
  tiktokTab.classList.remove('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
253
  document.getElementById('video-url').placeholder = 'https://www.youtube.com/watch?v=...';
254
- });
255
 
256
- tiktokTab.addEventListener('click', () => {
257
  tiktokTab.classList.add('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
258
  youtubeTab.classList.remove('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
259
  document.getElementById('video-url').placeholder = 'https://www.tiktok.com/@username/video/...';
260
- });
261
- // Transcript generation
 
 
 
 
 
 
262
  document.getElementById('generate-btn').addEventListener('click', async () => {
263
  const url = document.getElementById('video-url').value.trim();
264
  const urlPatterns = {
@@ -275,20 +284,27 @@
275
  alert('Please enter a valid YouTube or TikTok URL');
276
  return;
277
  }
278
-
279
  try {
280
  // Show loading state
281
  document.getElementById('empty-state').classList.add('hidden');
282
  document.getElementById('status-container').classList.remove('hidden');
283
  document.getElementById('results-container').classList.add('hidden');
284
  document.getElementById('generate-btn').disabled = true;
 
 
 
 
 
 
 
285
 
286
- // Mock API call - replace with actual API endpoint
287
- const [videoInfo, transcriptData] = await Promise.all([
288
  fetchVideoInfo(url),
289
  fetchTranscript(url)
290
  ]);
291
 
 
 
292
  // Update UI
293
  document.getElementById('status-container').classList.add('hidden');
294
  document.getElementById('results-container').classList.remove('hidden');
@@ -308,11 +324,18 @@
308
  document.getElementById('status-container').classList.add('hidden');
309
  document.getElementById('results-container').classList.add('hidden');
310
  document.getElementById('empty-state').classList.remove('hidden');
311
- alert('Error processing video. Please try again.');
 
 
 
 
 
312
  } finally {
313
  document.getElementById('generate-btn').disabled = false;
 
 
314
  }
315
- });
316
 
317
  // Helper functions
318
  async function fetchVideoInfo(url) {
@@ -353,23 +376,40 @@
353
  function countWords(text) {
354
  return text.split(/\s+/).filter(word => word.length > 0).length;
355
  }
356
- // Copy functionality
357
- document.getElementById('copy-btn').addEventListener('click', () => {
358
  const transcriptText = document.getElementById('transcript-content').textContent;
359
- navigator.clipboard.writeText(transcriptText).then(() => {
360
- const copyBtn = document.getElementById('copy-btn');
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  const originalText = copyBtn.innerHTML;
362
  copyBtn.innerHTML = '<i data-feather="check" class="w-4 h-4"></i> Copied!';
 
363
  feather.replace();
364
 
365
  setTimeout(() => {
366
  copyBtn.innerHTML = originalText;
 
367
  feather.replace();
368
  }, 2000);
369
- });
 
 
 
370
  });
371
-
372
- // Download functionality
373
  document.getElementById('download-btn').addEventListener('click', () => {
374
  const transcriptText = document.getElementById('transcript-content').textContent;
375
  const blob = new Blob([transcriptText], { type: 'text/plain' });
@@ -382,41 +422,66 @@
382
  document.body.removeChild(a);
383
  URL.revokeObjectURL(url);
384
  });
385
- // Dark mode detection and toggle
386
- if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
387
- document.documentElement.classList.add('dark');
388
- }
389
-
390
- const darkModeToggle = document.createElement('button');
391
- darkModeToggle.className = 'fixed top-4 right-4 bg-gray-200 dark:bg-gray-700 p-2 rounded-full z-50';
392
- darkModeToggle.innerHTML = document.documentElement.classList.contains('dark')
393
- ? '<i data-feather="sun" class="w-5 h-5"></i>'
394
- : '<i data-feather="moon" class="w-5 h-5"></i>';
395
- document.body.insertBefore(darkModeToggle, document.body.firstChild);
396
- darkModeToggle.addEventListener('click', () => {
397
- document.documentElement.classList.toggle('dark');
398
- const icon = darkModeToggle.querySelector('i');
399
- if (document.documentElement.classList.contains('dark')) {
400
- icon.setAttribute('data-feather', 'sun');
401
- } else {
402
- icon.setAttribute('data-feather', 'moon');
403
  }
404
- feather.replace();
405
- });
406
- // Error handling for API calls
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  window.addEventListener('error', function(e) {
408
- console.error('Script error:', e.message, 'in', e.filename, 'line', e.lineno);
409
- document.getElementById('status-container').classList.add('hidden');
 
 
 
 
 
 
410
  const errorDiv = document.createElement('div');
411
- errorDiv.className = 'bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4';
412
  errorDiv.innerHTML = `
413
- <strong class="font-bold">Error!</strong>
414
- <span class="block sm:inline">Something went wrong. Please refresh the page and try again.</span>
415
  `;
416
- document.querySelector('.container').prepend(errorDiv);
 
 
 
 
 
 
417
  });
418
 
419
- feather.replace();
 
 
 
 
 
420
  </script>
421
  </body>
422
  </html>
 
225
  </div>
226
 
227
  <script>
228
+ // Initialize Vanta.js background with error handling
229
+ try {
230
+ VANTA.GLOBE({
231
+ el: "#vanta-bg",
232
+ mouseControls: true,
233
+ touchControls: true,
234
+ gyroControls: false,
235
+ minHeight: 200.00,
236
+ minWidth: 200.00,
237
+ scale: 1.00,
238
+ scaleMobile: 1.00,
239
+ color: 0x6366f1,
240
+ backgroundColor: 0xffffff,
241
+ size: 0.8
242
+ });
243
+ } catch (e) {
244
+ console.error('Vanta.js initialization failed:', e);
245
+ document.getElementById('vanta-bg').style.backgroundColor = '#6366f1';
246
+ }
247
+ // Initialize feather icons
248
  feather.replace();
 
249
  // Tab switching functionality
250
  const youtubeTab = document.getElementById('youtube-tab');
251
  const tiktokTab = document.getElementById('tiktok-tab');
252
 
253
+ function switchToYoutube() {
254
  youtubeTab.classList.add('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
255
  tiktokTab.classList.remove('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
256
  document.getElementById('video-url').placeholder = 'https://www.youtube.com/watch?v=...';
257
+ }
258
 
259
+ function switchToTiktok() {
260
  tiktokTab.classList.add('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
261
  youtubeTab.classList.remove('active-tab', 'text-primary', 'dark:text-primary', 'border-primary');
262
  document.getElementById('video-url').placeholder = 'https://www.tiktok.com/@username/video/...';
263
+ }
264
+
265
+ youtubeTab.addEventListener('click', switchToYoutube);
266
+ tiktokTab.addEventListener('click', switchToTiktok);
267
+
268
+ // Set initial active tab
269
+ switchToYoutube();
270
+ // Transcript generation
271
  document.getElementById('generate-btn').addEventListener('click', async () => {
272
  const url = document.getElementById('video-url').value.trim();
273
  const urlPatterns = {
 
284
  alert('Please enter a valid YouTube or TikTok URL');
285
  return;
286
  }
 
287
  try {
288
  // Show loading state
289
  document.getElementById('empty-state').classList.add('hidden');
290
  document.getElementById('status-container').classList.remove('hidden');
291
  document.getElementById('results-container').classList.add('hidden');
292
  document.getElementById('generate-btn').disabled = true;
293
+ document.getElementById('generate-btn').innerHTML = '<i data-feather="loader" class="animate-spin w-5 h-5"></i> Processing...';
294
+ feather.replace();
295
+
296
+ // Simulate API call with timeout
297
+ const timeoutPromise = new Promise((_, reject) =>
298
+ setTimeout(() => reject(new Error('Request timeout')), 10000)
299
+ );
300
 
301
+ const apiPromise = Promise.all([
 
302
  fetchVideoInfo(url),
303
  fetchTranscript(url)
304
  ]);
305
 
306
+ const [videoInfo, transcriptData] = await Promise.race([apiPromise, timeoutPromise]);
307
+
308
  // Update UI
309
  document.getElementById('status-container').classList.add('hidden');
310
  document.getElementById('results-container').classList.remove('hidden');
 
324
  document.getElementById('status-container').classList.add('hidden');
325
  document.getElementById('results-container').classList.add('hidden');
326
  document.getElementById('empty-state').classList.remove('hidden');
327
+
328
+ const errorMessage = error.message.includes('timeout')
329
+ ? 'The request timed out. Please check your connection and try again.'
330
+ : 'Error processing video. Please try again.';
331
+
332
+ alert(errorMessage);
333
  } finally {
334
  document.getElementById('generate-btn').disabled = false;
335
+ document.getElementById('generate-btn').innerHTML = '<i data-feather="play" class="w-5 h-5"></i> Generate Transcript';
336
+ feather.replace();
337
  }
338
+ });
339
 
340
  // Helper functions
341
  async function fetchVideoInfo(url) {
 
376
  function countWords(text) {
377
  return text.split(/\s+/).filter(word => word.length > 0).length;
378
  }
379
+ // Copy functionality with fallback
380
+ document.getElementById('copy-btn').addEventListener('click', async () => {
381
  const transcriptText = document.getElementById('transcript-content').textContent;
382
+ const copyBtn = document.getElementById('copy-btn');
383
+
384
+ try {
385
+ if (navigator.clipboard) {
386
+ await navigator.clipboard.writeText(transcriptText);
387
+ } else {
388
+ // Fallback for older browsers
389
+ const textArea = document.createElement('textarea');
390
+ textArea.value = transcriptText;
391
+ document.body.appendChild(textArea);
392
+ textArea.select();
393
+ document.execCommand('copy');
394
+ document.body.removeChild(textArea);
395
+ }
396
+
397
  const originalText = copyBtn.innerHTML;
398
  copyBtn.innerHTML = '<i data-feather="check" class="w-4 h-4"></i> Copied!';
399
+ copyBtn.classList.add('bg-green-500', 'hover:bg-green-600');
400
  feather.replace();
401
 
402
  setTimeout(() => {
403
  copyBtn.innerHTML = originalText;
404
+ copyBtn.classList.remove('bg-green-500', 'hover:bg-green-600');
405
  feather.replace();
406
  }, 2000);
407
+ } catch (err) {
408
+ console.error('Failed to copy:', err);
409
+ alert('Failed to copy transcript. Please try again or copy manually.');
410
+ }
411
  });
412
+ // Download functionality
 
413
  document.getElementById('download-btn').addEventListener('click', () => {
414
  const transcriptText = document.getElementById('transcript-content').textContent;
415
  const blob = new Blob([transcriptText], { type: 'text/plain' });
 
422
  document.body.removeChild(a);
423
  URL.revokeObjectURL(url);
424
  });
425
+ // Dark mode detection and toggle with local storage
426
+ function initDarkMode() {
427
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
428
+ const storedMode = localStorage.getItem('darkMode');
429
+
430
+ if (storedMode === 'dark' || (storedMode === null && prefersDark)) {
431
+ document.documentElement.classList.add('dark');
 
 
 
 
 
 
 
 
 
 
 
432
  }
433
+
434
+ const darkModeToggle = document.createElement('button');
435
+ darkModeToggle.className = 'fixed top-4 right-4 bg-gray-200 dark:bg-gray-700 p-2 rounded-full z-50 transition-all';
436
+ darkModeToggle.setAttribute('aria-label', 'Toggle dark mode');
437
+ darkModeToggle.innerHTML = document.documentElement.classList.contains('dark')
438
+ ? '<i data-feather="sun" class="w-5 h-5"></i>'
439
+ : '<i data-feather="moon" class="w-5 h-5"></i>';
440
+ document.body.insertBefore(darkModeToggle, document.body.firstChild);
441
+
442
+ darkModeToggle.addEventListener('click', () => {
443
+ const isDark = document.documentElement.classList.toggle('dark');
444
+ localStorage.setItem('darkMode', isDark ? 'dark' : 'light');
445
+
446
+ const icon = darkModeToggle.querySelector('i');
447
+ icon.setAttribute('data-feather', isDark ? 'sun' : 'moon');
448
+ feather.replace();
449
+ });
450
+ }
451
+
452
+ // Initialize dark mode after DOM is loaded
453
+ document.addEventListener('DOMContentLoaded', initDarkMode);
454
+ // Global error handling
455
  window.addEventListener('error', function(e) {
456
+ console.error('Error:', e.message, 'in', e.filename, 'line', e.lineno);
457
+
458
+ // Hide any loading states
459
+ document.getElementById('status-container')?.classList.add('hidden');
460
+ document.getElementById('generate-btn').disabled = false;
461
+ document.getElementById('generate-btn').innerHTML = '<i data-feather="play" class="w-5 h-5"></i> Generate Transcript';
462
+
463
+ // Show error message
464
  const errorDiv = document.createElement('div');
465
+ errorDiv.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded z-50 flex items-center gap-2';
466
  errorDiv.innerHTML = `
467
+ <i data-feather="alert-triangle" class="w-5 h-5"></i>
468
+ <span>Something went wrong. Please try again.</span>
469
  `;
470
+ document.body.appendChild(errorDiv);
471
+ feather.replace();
472
+
473
+ setTimeout(() => {
474
+ errorDiv.classList.add('opacity-0', 'transition-opacity', 'duration-300');
475
+ setTimeout(() => errorDiv.remove(), 300);
476
+ }, 5000);
477
  });
478
 
479
+ // Initialize with loading states
480
+ document.addEventListener('DOMContentLoaded', () => {
481
+ feather.replace();
482
+ document.getElementById('empty-state').classList.remove('hidden');
483
+ });
484
+ feather.replace();
485
  </script>
486
  </body>
487
  </html>