Toowired commited on
Commit
c1a840b
·
verified ·
1 Parent(s): 4ba1281

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +348 -21
index.html CHANGED
@@ -1,4 +1,5 @@
1
- <!DOCTYPE html>
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
@@ -293,13 +294,14 @@
293
  <button id="uploadBtn" class="bg-blue-500 hover:bg-blue-600 text-white py-3 px-4 rounded-lg flex items-center justify-center transition">
294
  <i class="fas fa-upload mr-2"></i> Upload File
295
  </button>
296
- <button id="pasteBtn" class="bg-green-500 hover:green-600 text-white py-3 px-4 rounded-lg flex items-center justify-center transition">
297
  <i class="fas fa-paste mr-2"></i> Paste Text
298
  </button>
299
  <div id="dropzone" class="dropzone bg-gray-50 py-3 px-4 rounded-lg flex items-center justify-center cursor-pointer">
300
  <div class="text-center">
301
  <i class="fas fa-file-import text-2xl text-gray-400 mb-1"></i>
302
  <p class="text-gray-500">Drag & Drop File</p>
 
303
  </div>
304
  </div>
305
  </div>
@@ -2631,51 +2633,159 @@
2631
  }
2632
  });
2633
 
2634
- // File processing
2635
  function handleFile(file) {
 
 
 
 
 
 
 
2636
  const fileType = file.type;
2637
  const fileName = file.name.toLowerCase();
 
2638
 
2639
- if (fileType === 'text/plain' || fileName.endsWith('.txt')) {
2640
- readTextFile(file);
2641
- } else if (fileType === 'application/pdf' || fileName.endsWith('.pdf')) {
2642
- readPDFFile(file);
2643
- } else if (fileType === 'application/msword' ||
2644
- fileType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
2645
- fileName.endsWith('.doc') || fileName.endsWith('.docx')) {
2646
- showToast('Word document support requires conversion to text. Please save as plain text or PDF first.', 'error');
2647
- } else {
2648
- showToast('Unsupported file type. Please upload a TXT or PDF file.', 'error');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2649
  }
2650
  }
2651
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2652
  function readTextFile(file) {
2653
  const reader = new FileReader();
2654
  reader.onload = (e) => {
2655
- setDocumentContent(e.target.result);
 
 
 
2656
  };
2657
- reader.readAsText(file);
 
 
 
 
2658
  }
2659
 
 
2660
  function readPDFFile(file) {
2661
- // Check if PDF.js is available
2662
  if (typeof pdfjsLib === 'undefined') {
2663
- showToast('PDF.js not loaded. PDF support requires PDF.js library.', 'error');
 
2664
  return;
2665
  }
2666
 
2667
- // Show loading state
2668
- documentContent.innerHTML = '<div class="text-center py-8"><div class="loading-spinner mx-auto"></div><p class="text-gray-500 mt-2">Processing PDF file...</p></div>';
2669
 
2670
- // Load PDF.js
2671
- pdfjsLib.getDocument(URL.createObjectURL(file)).promise.then(pdf => {
2672
  let text = '';
2673
  const numPages = pdf.numPages;
2674
  const pagePromises = [];
2675
 
 
 
 
2676
  for (let i = 1; i <= numPages; i++) {
2677
  pagePromises.push(pdf.getPage(i).then(page => {
2678
  return page.getTextContent().then(textContent => {
 
 
 
 
 
 
 
 
 
 
 
 
2679
  return textContent.items.map(item => item.str).join(' ');
2680
  });
2681
  }));
@@ -2684,16 +2794,233 @@
2684
  Promise.all(pagePromises).then(pagesText => {
2685
  text = pagesText.join('\n\n');
2686
  setDocumentContent(text);
 
 
 
2687
  }).catch(error => {
2688
  console.error('Error extracting PDF text:', error);
2689
  showToast('Failed to extract text from PDF', 'error');
 
 
2690
  });
2691
  }).catch(error => {
2692
  console.error('Error loading PDF:', error);
2693
  showToast('Failed to load PDF file', 'error');
 
 
2694
  });
2695
  }
2696
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2697
  // Set document content
2698
  function setDocumentContent(text) {
2699
  currentText = text;
 
1
+ <input type="file" id="fileInput" class="hidden" accept=".txt,.pdf,.doc,.docx,.odt,.rtf,.md,.markdown,.json,.html,.htm,.xml,.csv,.epub">&lt;/antml:parameter>
2
+ <parameter name="old_str"> <input type="file" id="fileInput" class="hidden" accept=".txt,.pdf,.doc,.docx,.odt,.rtf"><!DOCTYPE html>
3
  <html lang="en">
4
  <head>
5
  <meta charset="UTF-8">
 
294
  <button id="uploadBtn" class="bg-blue-500 hover:bg-blue-600 text-white py-3 px-4 rounded-lg flex items-center justify-center transition">
295
  <i class="fas fa-upload mr-2"></i> Upload File
296
  </button>
297
+ <button id="pasteBtn" class="bg-green-500 hover:bg-green-600 text-white py-3 px-4 rounded-lg flex items-center justify-center transition">
298
  <i class="fas fa-paste mr-2"></i> Paste Text
299
  </button>
300
  <div id="dropzone" class="dropzone bg-gray-50 py-3 px-4 rounded-lg flex items-center justify-center cursor-pointer">
301
  <div class="text-center">
302
  <i class="fas fa-file-import text-2xl text-gray-400 mb-1"></i>
303
  <p class="text-gray-500">Drag & Drop File</p>
304
+ <p class="text-xs text-gray-400 mt-1">Supports: TXT, PDF, DOC/DOCX, RTF, MD, JSON, HTML, XML, CSV</p>
305
  </div>
306
  </div>
307
  </div>
 
2633
  }
2634
  });
2635
 
2636
+ // Enhanced file processing with size validation and progress
2637
  function handleFile(file) {
2638
+ // Validate file size (50MB limit)
2639
+ const maxSize = 50 * 1024 * 1024; // 50MB
2640
+ if (file.size > maxSize) {
2641
+ showToast('File too large. Please upload a file smaller than 50MB.', 'error');
2642
+ return;
2643
+ }
2644
+
2645
  const fileType = file.type;
2646
  const fileName = file.name.toLowerCase();
2647
+ const fileExtension = fileName.split('.').pop();
2648
 
2649
+ // Show processing progress
2650
+ showFileProgress(fileName, 'processing');
2651
+ documentContent.innerHTML = `
2652
+ <div class="text-center py-8">
2653
+ <div class="loading-spinner mx-auto"></div>
2654
+ <p class="text-gray-500 mt-2">Processing ${fileName}...</p>
2655
+ <p class="text-xs text-gray-400 mt-1">File size: ${formatFileSize(file.size)}</p>
2656
+ </div>
2657
+ `;
2658
+
2659
+ try {
2660
+ switch (fileExtension) {
2661
+ case 'txt':
2662
+ readTextFile(file);
2663
+ break;
2664
+ case 'pdf':
2665
+ readPDFFile(file);
2666
+ break;
2667
+ case 'doc':
2668
+ case 'docx':
2669
+ readWordDocument(file);
2670
+ break;
2671
+ case 'rtf':
2672
+ readRTFFile(file);
2673
+ break;
2674
+ case 'md':
2675
+ case 'markdown':
2676
+ readMarkdownFile(file);
2677
+ break;
2678
+ case 'json':
2679
+ readJSONFile(file);
2680
+ break;
2681
+ case 'html':
2682
+ case 'htm':
2683
+ readHTMLFile(file);
2684
+ break;
2685
+ case 'xml':
2686
+ readXMLFile(file);
2687
+ break;
2688
+ case 'csv':
2689
+ readCSVFile(file);
2690
+ break;
2691
+ case 'odt':
2692
+ throw new Error('ODT files require conversion. Please save as DOC/DOCX or PDF.');
2693
+ case 'epub':
2694
+ throw new Error('EPUB files are not yet supported. Please extract text manually.');
2695
+ default:
2696
+ // Try to read as plain text if unknown extension
2697
+ if (fileType.startsWith('text/')) {
2698
+ readTextFile(file);
2699
+ } else {
2700
+ throw new Error(`Unsupported file type: .${fileExtension}. Please upload a supported document format.`);
2701
+ }
2702
+ }
2703
+ } catch (error) {
2704
+ console.error('Error processing file:', error);
2705
+ showToast('Error processing file: ' + error.message, 'error');
2706
+ documentContent.innerHTML = '<p class="text-gray-500 italic">Error loading document. Please try again.</p>';
2707
+ showFileProgress(fileName, 'error');
2708
  }
2709
  }
2710
 
2711
+ // File progress indicator
2712
+ function showFileProgress(fileName, status) {
2713
+ const progressEl = document.getElementById('fileProgress');
2714
+ if (!progressEl) {
2715
+ const progress = document.createElement('div');
2716
+ progress.id = 'fileProgress';
2717
+ progress.className = 'fixed bottom-4 right-4 bg-white border border-gray-200 rounded-lg shadow-lg p-3 z-50';
2718
+ document.body.appendChild(progress);
2719
+ }
2720
+
2721
+ const progressEl2 = document.getElementById('fileProgress');
2722
+ const statusIcons = {
2723
+ processing: '<i class="fas fa-spinner fa-spin text-blue-500 mr-2"></i>',
2724
+ success: '<i class="fas fa-check-circle text-green-500 mr-2"></i>',
2725
+ error: '<i class="fas fa-times-circle text-red-500 mr-2"></i>'
2726
+ };
2727
+
2728
+ progressEl2.innerHTML = `
2729
+ ${statusIcons[status]}
2730
+ <span class="text-sm">${fileName}</span>
2731
+ `;
2732
+
2733
+ if (status !== 'processing') {
2734
+ setTimeout(() => {
2735
+ progressEl2.remove();
2736
+ }, 3000);
2737
+ }
2738
+ }
2739
+
2740
+ // Enhanced text file reader with encoding detection
2741
  function readTextFile(file) {
2742
  const reader = new FileReader();
2743
  reader.onload = (e) => {
2744
+ const text = e.target.result;
2745
+ setDocumentContent(text);
2746
+ showFileProgress(file.name, 'success');
2747
+ showToast(`Loaded ${formatFileSize(file.size)} text file`, 'success');
2748
  };
2749
+ reader.onerror = () => {
2750
+ showToast('Error reading text file', 'error');
2751
+ showFileProgress(file.name, 'error');
2752
+ };
2753
+ reader.readAsText(file, 'UTF-8');
2754
  }
2755
 
2756
+ // Enhanced PDF reader with progress
2757
  function readPDFFile(file) {
 
2758
  if (typeof pdfjsLib === 'undefined') {
2759
+ showToast('PDF.js not loaded. Refreshing page...', 'error');
2760
+ setTimeout(() => window.location.reload(), 2000);
2761
  return;
2762
  }
2763
 
2764
+ const fileURL = URL.createObjectURL(file);
 
2765
 
2766
+ pdfjsLib.getDocument(fileURL).promise.then(pdf => {
 
2767
  let text = '';
2768
  const numPages = pdf.numPages;
2769
  const pagePromises = [];
2770
 
2771
+ // Update progress as pages are processed
2772
+ let pagesProcessed = 0;
2773
+
2774
  for (let i = 1; i <= numPages; i++) {
2775
  pagePromises.push(pdf.getPage(i).then(page => {
2776
  return page.getTextContent().then(textContent => {
2777
+ pagesProcessed++;
2778
+ const progress = (pagesProcessed / numPages) * 100;
2779
+ documentContent.innerHTML = `
2780
+ <div class="text-center py-8">
2781
+ <div class="loading-spinner mx-auto"></div>
2782
+ <p class="text-gray-500 mt-2">Processing PDF...</p>
2783
+ <div class="w-32 bg-gray-200 rounded-full h-2 mx-auto mt-3">
2784
+ <div class="bg-blue-600 h-2 rounded-full transition-all duration-300" style="width: ${progress}%"></div>
2785
+ </div>
2786
+ <p class="text-xs text-gray-400 mt-2">${pagesProcessed}/${numPages} pages</p>
2787
+ </div>
2788
+ `;
2789
  return textContent.items.map(item => item.str).join(' ');
2790
  });
2791
  }));
 
2794
  Promise.all(pagePromises).then(pagesText => {
2795
  text = pagesText.join('\n\n');
2796
  setDocumentContent(text);
2797
+ URL.revokeObjectURL(fileURL);
2798
+ showFileProgress(file.name, 'success');
2799
+ showToast(`Loaded PDF with ${numPages} pages`, 'success');
2800
  }).catch(error => {
2801
  console.error('Error extracting PDF text:', error);
2802
  showToast('Failed to extract text from PDF', 'error');
2803
+ URL.revokeObjectURL(fileURL);
2804
+ showFileProgress(file.name, 'error');
2805
  });
2806
  }).catch(error => {
2807
  console.error('Error loading PDF:', error);
2808
  showToast('Failed to load PDF file', 'error');
2809
+ URL.revokeObjectURL(fileURL);
2810
+ showFileProgress(file.name, 'error');
2811
  });
2812
  }
2813
 
2814
+ // Word document reader (.doc/.docx)
2815
+ function readWordDocument(file) {
2816
+ const reader = new FileReader();
2817
+ reader.onload = async (e) => {
2818
+ try {
2819
+ // Use mammoth to convert docx to text
2820
+ const result = await mammoth.extractRawText({arrayBuffer: e.target.result});
2821
+ setDocumentContent(result.value);
2822
+
2823
+ if (result.messages.length > 0) {
2824
+ console.warn('Word processing warnings:', result.messages);
2825
+ }
2826
+ } catch (error) {
2827
+ console.error('Error reading Word document:', error);
2828
+ showToast('Error reading Word document. Please try saving as a different format.', 'error');
2829
+ }
2830
+ };
2831
+ reader.onerror = () => {
2832
+ showToast('Error reading Word document', 'error');
2833
+ };
2834
+ reader.readAsArrayBuffer(file);
2835
+ }
2836
+
2837
+ // RTF file reader
2838
+ function readRTFFile(file) {
2839
+ const reader = new FileReader();
2840
+ reader.onload = (e) => {
2841
+ let rtfText = e.target.result;
2842
+
2843
+ // Basic RTF to plain text conversion
2844
+ // Remove RTF control codes
2845
+ rtfText = rtfText.replace(/\\[a-z]+[0-9]*\s?/gi, '');
2846
+ rtfText = rtfText.replace(/[{}]/g, '');
2847
+ rtfText = rtfText.replace(/\\\\/g, '\\');
2848
+ rtfText = rtfText.replace(/\\'/g, "'");
2849
+ rtfText = rtfText.replace(/\\\n/g, '\n');
2850
+ rtfText = rtfText.replace(/\s+/g, ' ');
2851
+ rtfText = rtfText.trim();
2852
+
2853
+ setDocumentContent(rtfText);
2854
+ };
2855
+ reader.onerror = () => {
2856
+ showToast('Error reading RTF file', 'error');
2857
+ };
2858
+ reader.readAsText(file);
2859
+ }
2860
+
2861
+ // Markdown file reader
2862
+ function readMarkdownFile(file) {
2863
+ const reader = new FileReader();
2864
+ reader.onload = (e) => {
2865
+ let text = e.target.result;
2866
+
2867
+ // Convert basic Markdown to plain text
2868
+ // Remove Markdown syntax for better TTS
2869
+ text = text.replace(/^#{1,6}\s+/gm, ''); // Headers
2870
+ text = text.replace(/\*\*(.*?)\*\*/g, '$1'); // Bold
2871
+ text = text.replace(/\*(.*?)\*/g, '$1'); // Italic
2872
+ text = text.replace(/_(.*?)_/g, '$1'); // Italic underscore
2873
+ text = text.replace(/`(.*?)`/g, '$1'); // Inline code
2874
+ text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); // Links
2875
+ text = text.replace(/!\[([^\]]*)\]\([^)]+\)/g, ''); // Images
2876
+ text = text.replace(/^>\s+/gm, ''); // Blockquotes
2877
+ text = text.replace(/^[\s]*-\s+/gm, '• '); // Unordered lists
2878
+ text = text.replace(/^[\s]*\d+\.\s+/gm, ''); // Ordered lists
2879
+ text = text.replace(/---+/g, ''); // Horizontal rules
2880
+ text = text.replace(/\n{3,}/g, '\n\n'); // Multiple newlines
2881
+
2882
+ setDocumentContent(text);
2883
+ };
2884
+ reader.onerror = () => {
2885
+ showToast('Error reading Markdown file', 'error');
2886
+ };
2887
+ reader.readAsText(file);
2888
+ }
2889
+
2890
+ // JSON file reader
2891
+ function readJSONFile(file) {
2892
+ const reader = new FileReader();
2893
+ reader.onload = (e) => {
2894
+ try {
2895
+ const jsonData = JSON.parse(e.target.result);
2896
+
2897
+ // Convert JSON to readable text
2898
+ let text = '';
2899
+
2900
+ function jsonToText(obj, prefix = '') {
2901
+ for (const [key, value] of Object.entries(obj)) {
2902
+ if (typeof value === 'object' && value !== null) {
2903
+ text += `${prefix}${key}:\n`;
2904
+ jsonToText(value, prefix + ' ');
2905
+ } else {
2906
+ text += `${prefix}${key}: ${value}\n`;
2907
+ }
2908
+ }
2909
+ }
2910
+
2911
+ jsonToText(jsonData);
2912
+ setDocumentContent(text);
2913
+ } catch (error) {
2914
+ showToast('Invalid JSON file', 'error');
2915
+ }
2916
+ };
2917
+ reader.onerror = () => {
2918
+ showToast('Error reading JSON file', 'error');
2919
+ };
2920
+ reader.readAsText(file);
2921
+ }
2922
+
2923
+ // HTML file reader
2924
+ function readHTMLFile(file) {
2925
+ const reader = new FileReader();
2926
+ reader.onload = (e) => {
2927
+ const htmlContent = e.target.result;
2928
+
2929
+ // Create a temporary DOM element to extract text
2930
+ const tempDiv = document.createElement('div');
2931
+ tempDiv.innerHTML = htmlContent;
2932
+
2933
+ // Remove script and style tags
2934
+ const scripts = tempDiv.querySelectorAll('script, style');
2935
+ scripts.forEach(script => script.remove());
2936
+
2937
+ // Extract text content
2938
+ let text = tempDiv.textContent || tempDiv.innerText || '';
2939
+
2940
+ // Clean up whitespace
2941
+ text = text.replace(/\s+/g, ' ');
2942
+ text = text.replace(/\n\s*\n/g, '\n\n');
2943
+ text = text.trim();
2944
+
2945
+ setDocumentContent(text);
2946
+ };
2947
+ reader.onerror = () => {
2948
+ showToast('Error reading HTML file', 'error');
2949
+ };
2950
+ reader.readAsText(file);
2951
+ }
2952
+
2953
+ // XML file reader
2954
+ function readXMLFile(file) {
2955
+ const reader = new FileReader();
2956
+ reader.onload = (e) => {
2957
+ try {
2958
+ const xmlContent = e.target.result;
2959
+ const parser = new DOMParser();
2960
+ const xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
2961
+
2962
+ // Extract text content from XML
2963
+ let text = '';
2964
+
2965
+ function extractText(node) {
2966
+ if (node.nodeType === Node.TEXT_NODE) {
2967
+ text += node.textContent + ' ';
2968
+ } else if (node.nodeType === Node.ELEMENT_NODE) {
2969
+ for (const child of node.childNodes) {
2970
+ extractText(child);
2971
+ }
2972
+ }
2973
+ }
2974
+
2975
+ extractText(xmlDoc.documentElement);
2976
+
2977
+ // Clean up text
2978
+ text = text.replace(/\s+/g, ' ');
2979
+ text = text.trim();
2980
+
2981
+ setDocumentContent(text);
2982
+ } catch (error) {
2983
+ showToast('Error parsing XML file', 'error');
2984
+ }
2985
+ };
2986
+ reader.onerror = () => {
2987
+ showToast('Error reading XML file', 'error');
2988
+ };
2989
+ reader.readAsText(file);
2990
+ }
2991
+
2992
+ // CSV file reader
2993
+ function readCSVFile(file) {
2994
+ const reader = new FileReader();
2995
+ reader.onload = (e) => {
2996
+ const csvContent = e.target.result;
2997
+
2998
+ // Parse CSV (simple implementation)
2999
+ const lines = csvContent.split('\n').filter(line => line.trim());
3000
+ const headers = lines[0].split(',').map(h => h.trim().replace(/"/g, ''));
3001
+
3002
+ let text = `CSV Data Summary:\n\n`;
3003
+ text += `Headers: ${headers.join(', ')}\n\n`;
3004
+ text += `Total rows: ${lines.length - 1}\n\n`;
3005
+
3006
+ // Add first few rows as example
3007
+ if (lines.length > 1) {
3008
+ text += 'First few rows:\n';
3009
+ for (let i = 1; i <= Math.min(5, lines.length - 1); i++) {
3010
+ const values = lines[i].split(',').map(v => v.trim().replace(/"/g, ''));
3011
+ text += `Row ${i}: ${values.join(', ')}\n`;
3012
+ }
3013
+ }
3014
+
3015
+ setDocumentContent(text);
3016
+ showToast('CSV file loaded. Showing data summary for TTS.', 'success');
3017
+ };
3018
+ reader.onerror = () => {
3019
+ showToast('Error reading CSV file', 'error');
3020
+ };
3021
+ reader.readAsText(file);
3022
+ }
3023
+
3024
  // Set document content
3025
  function setDocumentContent(text) {
3026
  currentText = text;