first commit
This commit is contained in:
228
static/js/pdf-handler.js
Normal file
228
static/js/pdf-handler.js
Normal file
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* Document Handler Module (PDF, DOCX, DOC)
|
||||
* UPDATED: Updates workflow progress after document load
|
||||
*/
|
||||
|
||||
function initPdfHandler() {
|
||||
const uploadZone = document.getElementById('uploadZone');
|
||||
const docInput = document.getElementById('docInput');
|
||||
|
||||
if (!uploadZone || !docInput) return;
|
||||
|
||||
uploadZone.addEventListener('click', (e) => {
|
||||
if (e.target.closest('button')) return;
|
||||
docInput.click();
|
||||
});
|
||||
|
||||
docInput.addEventListener('change', (e) => {
|
||||
const file = e.target.files[0];
|
||||
if (file) {
|
||||
handleDocumentFile(file);
|
||||
}
|
||||
});
|
||||
|
||||
uploadZone.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
uploadZone.classList.add('drag-over');
|
||||
});
|
||||
|
||||
uploadZone.addEventListener('dragleave', () => {
|
||||
uploadZone.classList.remove('drag-over');
|
||||
});
|
||||
|
||||
uploadZone.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
uploadZone.classList.remove('drag-over');
|
||||
|
||||
const files = e.dataTransfer.files;
|
||||
if (files.length > 0) {
|
||||
const file = files[0];
|
||||
const name = file.name.toLowerCase();
|
||||
|
||||
if (name.endsWith('.pdf') || name.endsWith('.docx') || name.endsWith('.doc')) {
|
||||
handleDocumentFile(file);
|
||||
} else {
|
||||
alert('Please drop a valid PDF, DOCX, or DOC file.');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('📄 Document handler initialized (PDF, DOCX, DOC)');
|
||||
}
|
||||
|
||||
function handleDocumentFile(file) {
|
||||
const name = file.name.toLowerCase();
|
||||
|
||||
if (name.endsWith('.pdf')) {
|
||||
handlePdfFile(file);
|
||||
} else if (name.endsWith('.docx') || name.endsWith('.doc')) {
|
||||
handleWordFile(file);
|
||||
} else {
|
||||
alert('Unsupported file type. Please upload a PDF, DOCX, or DOC file.');
|
||||
}
|
||||
}
|
||||
|
||||
async function handlePdfFile(file) {
|
||||
if (!file.name.toLowerCase().endsWith('.pdf')) {
|
||||
alert('Please select a valid PDF file.');
|
||||
return;
|
||||
}
|
||||
|
||||
showLoader('Processing PDF...', `Extracting content from ${file.name}`);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/upload-pdf', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
console.log(`✅ PDF processed: ${data.page_count} pages, ${data.blocks.length} blocks`);
|
||||
|
||||
const projectName = file.name.replace('.pdf', '');
|
||||
document.getElementById('projectName').value = projectName;
|
||||
currentProject.name = projectName;
|
||||
|
||||
renderDocumentBlocks(data.blocks);
|
||||
|
||||
document.getElementById('uploadSection').style.display = 'none';
|
||||
document.getElementById('editorSection').style.display = 'block';
|
||||
|
||||
hideLoader();
|
||||
showNotification(`PDF processed: ${data.blocks.length} blocks extracted`, 'success');
|
||||
updateWorkflowProgress('edit');
|
||||
|
||||
} catch (error) {
|
||||
hideLoader();
|
||||
console.error('PDF processing error:', error);
|
||||
alert('Failed to process PDF: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleWordFile(file) {
|
||||
const name = file.name.toLowerCase();
|
||||
if (!name.endsWith('.docx') && !name.endsWith('.doc')) {
|
||||
alert('Please select a valid DOCX or DOC file.');
|
||||
return;
|
||||
}
|
||||
|
||||
const fileType = name.endsWith('.docx') ? 'DOCX' : 'DOC';
|
||||
showLoader(`Processing ${fileType}...`, `Extracting content from ${file.name}`);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/upload-docx', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
console.log(`✅ ${fileType} processed: ${data.blocks.length} blocks`);
|
||||
|
||||
const projectName = file.name.replace(/\.(docx|doc)$/i, '');
|
||||
document.getElementById('projectName').value = projectName;
|
||||
currentProject.name = projectName;
|
||||
|
||||
renderDocumentBlocks(data.blocks);
|
||||
|
||||
document.getElementById('uploadSection').style.display = 'none';
|
||||
document.getElementById('editorSection').style.display = 'block';
|
||||
|
||||
hideLoader();
|
||||
showNotification(`${fileType} processed: ${data.blocks.length} blocks extracted`, 'success');
|
||||
updateWorkflowProgress('edit');
|
||||
|
||||
} catch (error) {
|
||||
hideLoader();
|
||||
console.error(`${fileType} processing error:`, error);
|
||||
alert(`Failed to process ${fileType}: ` + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
function renderDocumentBlocks(blocks) {
|
||||
const editor = document.getElementById('markdownEditor');
|
||||
editor.innerHTML = '';
|
||||
editorBlocks = [];
|
||||
|
||||
const emptyMessage = document.getElementById('emptyEditorMessage');
|
||||
if (emptyMessage) {
|
||||
emptyMessage.style.display = 'none';
|
||||
}
|
||||
|
||||
addChapterMarker(1);
|
||||
|
||||
for (const block of blocks) {
|
||||
let type = 'paragraph';
|
||||
let content = block.content || '';
|
||||
|
||||
if (block.type === 'image') {
|
||||
type = 'image';
|
||||
} else if (block.type === 'heading1' || content.startsWith('# ')) {
|
||||
type = 'heading1';
|
||||
} else if (block.type === 'heading2' || content.startsWith('## ')) {
|
||||
type = 'heading2';
|
||||
} else if (block.type === 'heading3' || content.startsWith('### ')) {
|
||||
type = 'heading3';
|
||||
} else if (block.type === 'list_item' || content.startsWith('- ')) {
|
||||
type = 'bulletList';
|
||||
} else if (block.type === 'quote' || content.startsWith('> ')) {
|
||||
type = 'quote';
|
||||
} else if (block.type === 'table') {
|
||||
type = 'table';
|
||||
}
|
||||
|
||||
let images = [];
|
||||
if (block.type === 'image' && block.data) {
|
||||
images = [{
|
||||
data: block.data,
|
||||
format: block.format || 'png',
|
||||
alt_text: 'Document Image',
|
||||
position: 'before'
|
||||
}];
|
||||
content = ``;
|
||||
}
|
||||
|
||||
const lastChild = editor.lastElementChild;
|
||||
const blockId = addBlock(type, content, lastChild, images);
|
||||
|
||||
if (block.type === 'image' && block.data) {
|
||||
const blockEl = document.getElementById(blockId);
|
||||
if (blockEl) {
|
||||
const contentDiv = blockEl.querySelector('.md-block-content');
|
||||
if (contentDiv) {
|
||||
contentDiv.innerHTML = `
|
||||
<div class="image-block">
|
||||
<img src="data:image/${block.format || 'png'};base64,${block.data}" alt="Document Image">
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const blockEl = document.getElementById(blockId);
|
||||
if (blockEl) {
|
||||
ensureNewBlockLineAfter(blockEl);
|
||||
}
|
||||
}
|
||||
|
||||
repairAllNewBlockLines();
|
||||
}
|
||||
|
||||
function renderPdfBlocks(blocks) {
|
||||
renderDocumentBlocks(blocks);
|
||||
}
|
||||
Reference in New Issue
Block a user