Cyleux's picture
Update index.html
8537253 verified
raw
history blame
11.1 kB
<!DOCTYPE html>
<html>
<head>
<title>File Chat</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.9.359/pdf.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/tesseract.min.js"></script>
<script src="https://unpkg.com/[email protected]/mammoth.browser.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
color: #333;
}
.file-upload {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.file-upload input[type="file"] {
display: none;
}
.file-upload label {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
cursor: pointer;
border-radius: 4px;
}
.file-upload label:hover {
background-color: #45a049;
}
.text-block {
margin-bottom: 20px;
padding: 10px;
background-color: white;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.file-name {
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
.loading {
margin-top: 10px;
font-style: italic;
color: #888;
}
.no-valid-text {
color: red;
font-weight: bold;
}
.remove-file {
margin-left: 10px;
color: red;
cursor: pointer;
}
.chat-container {
margin-top: 20px;
background-color: white;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.chat-header {
padding: 10px;
background-color: #4CAF50;
color: white;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.chat-history {
height: 300px;
overflow-y: scroll;
padding: 10px;
}
.user-message {
background-color: #e1f3fb;
padding: 10px;
margin-bottom: 10px;
border-radius: 4px;
}
.assistant-message {
background-color: #f0f0f0;
padding: 10px;
margin-bottom: 10px;
border-radius: 4px;
}
.chat-input {
display: flex;
align-items: center;
padding: 10px;
}
.chat-input input[type="text"] {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.chat-input button {
margin-left: 10px;
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.chat-input button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<div class="container">
<h1>OpenCall.ai File Chat</h1> <div class="file-upload">
<input type="file" id="fileUpload" accept=".txt,.doc,.docx,.pdf,.html,.htm,.jpg,.jpeg,.png" multiple>
<label for="fileUpload"><i class="fas fa-file-upload"></i> Choose Files</label>
</div>
<div id="textContent"></div>
<div class="chat-container" style="display: none;">
<div class="chat-header">
<h2>Chat with AI</h2>
</div>
<div class="chat-history" id="chatHistory"></div>
<div class="chat-input">
<input type="text" id="userInput" placeholder="Enter your query">
<button id="sendButton"><i class="fas fa-paper-plane"></i> Send</button>
</div>
</div>
</div>
<script>
const fileUpload = document.getElementById('fileUpload');
const textContent = document.getElementById('textContent');
const chatContainer = document.querySelector('.chat-container');
const chatHistory = document.getElementById('chatHistory');
const userInput = document.getElementById('userInput');
const sendButton = document.getElementById('sendButton');
let extractedContent = '';
let chatMessages = [];
fileUpload.addEventListener('change', handleFileUpload);
sendButton.addEventListener('click', sendQuery);
function handleFileUpload(event) {
const files = event.target.files;
for (let i = 0; i < files.length; i++) {
const file = files[i];
const fileReader = new FileReader();
const textBlock = document.createElement('div');
textBlock.className = 'text-block';
textBlock.innerHTML = `
<div>
<span class="file-name">${file.name}</span>
<span class="remove-file" data-index="${textContent.children.length}"><i class="fas fa-times"></i></span>
</div>
<div class="text-content"></div>
<div class="loading">Loading...</div>
`;
textContent.appendChild(textBlock);
fileReader.onload = function() {
const content = fileReader.result;
if (file.type === 'application/pdf') {
extractTextFromPDF(content, textBlock);
} else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
extractTextFromDocx(content, textBlock);
} else if (file.type.startsWith('image/')) {
extractTextFromImage(content, textBlock);
} else {
const extractedText = extractText(content);
displayText(extractedText, textBlock);
}
};
if (file.type === 'application/pdf') {
fileReader.readAsArrayBuffer(file);
} else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
fileReader.readAsArrayBuffer(file);
} else if (file.type.startsWith('image/')) {
fileReader.readAsDataURL(file);
} else {
fileReader.readAsText(file);
}
}
chatContainer.style.display = 'block';
}
function extractTextFromPDF(content, textBlock) {
pdfjsLib.getDocument({ data: content }).promise.then(function(pdf) {
const numPages = pdf.numPages;
let extractedText = '';
const extractPageText = function(pageNum) {
pdf.getPage(pageNum).then(function(page) {
page.getTextContent().then(function(textContent) {
extractedText += textContent.items.map(item => item.str).join(' ');
if (pageNum < numPages) {
extractPageText(pageNum + 1);
} else {
displayText(extractedText, textBlock);
}
});
});
};
extractPageText(1);
}).catch(function(error) {
console.error('Error extracting text from PDF:', error);
displayText('Error extracting text from PDF. Please try again.', textBlock);
});
}
function extractTextFromDocx(content, textBlock) {
mammoth.extractRawText({ arrayBuffer: content })
.then(function(result) {
const extractedText = result.value;
displayText(extractedText, textBlock);
})
.catch(function(error) {
console.error('Error extracting text from DOCX:', error);
displayText('Error extracting text from DOCX. Please try again.', textBlock);
});
}
function extractTextFromImage(content, textBlock) {
Tesseract.recognize(content)
.then(function(result) {
const extractedText = result.data.text;
displayText(extractedText, textBlock);
})
.catch(function(error) {
console.error('Error extracting text from image:', error);
displayText('Error extracting text from image. Please try again.', textBlock);
});
}
function extractText(content) {
const lines = content.split('\n');
const extractedLines = lines.filter(line => line.trim() !== '');
return extractedLines.join('\n');
}
function displayText(text, textBlock) {
const textContent = textBlock.querySelector('.text-content');
const loadingIndicator = textBlock.querySelector('.loading');
textContent.textContent = text;
loadingIndicator.style.display = 'none';
const paragraphs = text.split('\n\n');
const validParagraphs = paragraphs.filter(isValidText);
if (validParagraphs.length === 0) {
textBlock.classList.add('no-valid-text');
textContent.textContent = 'No valid text found in the file.';
} else {
extractedContent += `${textBlock.querySelector('.file-name').textContent}\n${validParagraphs.join('\n\n')}\n\n`;
}
}
function isValidText(text) {
const letterRegex = /[a-zA-Z]/g;
const nonLetterRegex = /[^a-zA-Z]/g;
const letterCount = (text.match(letterRegex) || []).length;
const nonLetterCount = (text.match(nonLetterRegex) || []).length;
return letterCount > nonLetterCount;
}
function sendQuery() {
const query = userInput.value.trim();
if (query === '') return;
const userMessage = document.createElement('div');
userMessage.className = 'user-message';
userMessage.textContent = 'User: ' + query;
chatHistory.appendChild(userMessage);
chatMessages.push({ role: 'user', content: query });
const requestData = {
model: "gradientai/Llama-3-8B-Instruct-Gradient-1048k",
messages: [
{
role: "system",
content: extractedContent
},
...chatMessages,
{
role: "user",
content: "'Based on the above context, please answer the following query: " + query
}
],
max_tokens: 400,
top_p: 0.9,
temperature: 0.8
};
fetch('https://azure5.ngrok.app/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestData)
})
.then(response => response.json())
.then(data => {
const assistantMessage = document.createElement('div');
assistantMessage.className = 'assistant-message';
assistantMessage.textContent = 'Assistant: ' + data.choices[0].message.content;
chatHistory.appendChild(assistantMessage);
chatHistory.scrollTop = chatHistory.scrollHeight;
chatMessages.push({ role: 'assistant', content: data.choices[0].message.content });
})
.catch(error => {
console.error('Error:', error);
const errorMessage = document.createElement('div');
errorMessage.className = 'assistant-message';
errorMessage.textContent = 'Error: Failed to get response from the model.';
chatHistory.appendChild(errorMessage);
});
userInput.value = '';
}
textContent.addEventListener('click', function(event) {
if (event.target.classList.contains('remove-file')) {
const index = event.target.dataset.index;
textContent.removeChild(textContent.children[index]);
}
});
</script>
</body>
</html>