triflix's picture
Update templates/index.html
cbba23d verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Upload Images for Generative AI</title>
<script src="https://cdn.tailwindcss.com"></script>
<!-- Marked library to render markdown results -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-4">
<h1 class="text-3xl font-bold text-center mb-6">Upload Images</h1>
<div class="flex flex-col items-center">
<!-- Upload/Paste Area -->
<div id="upload-area" class="border-2 border-dashed border-gray-400 p-8 rounded w-full sm:w-11/12 md:w-3/4 lg:w-1/2 bg-white">
<p class="mb-4 text-center">
Paste images with <strong>Ctrl + V</strong> or click "Add Image".
</p>
<input type="file" id="fileInput" name="files" accept="image/*" multiple class="hidden" />
<button id="addImageBtn" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mb-4">
Add Image
</button>
<!-- Thumbnails container -->
<div id="thumbnails" class="flex flex-wrap gap-4"></div>
</div>
<!-- Send Button -->
<div class="mt-6">
<button id="sendBtn" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
Send
</button>
</div>
<!-- Result Display -->
<div id="resultArea" class="mt-6 w-full sm:w-11/12 md:w-3/4 lg:w-1/2 overflow-x-auto"></div>
</div>
</div>
<!-- Popup Card for First Time -->
<div id="popupCard" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
<div class="bg-white rounded-lg p-6 w-11/12 sm:max-w-md mx-auto shadow-2xl transform transition-all duration-300">
<div class="mb-4">
<h2 class="text-2xl font-bold">πŸ‘‹ Hey, I'm Aditya Devarshi</h2>
<p class="mt-2 text-gray-700">I'm an AI Engineer πŸ€–, here to help with your assignments πŸ“š, support multiple images πŸ“·, and provide keyboard shortcuts ⌨️.</p>
<p class="mt-2 text-gray-700">Connect with me:</p>
<ul class="list-disc list-inside mt-2 text-blue-600">
<li><a href="https://www.adityadevarshi.online/" target="_blank">🌐 Website</a></li>
<li><a href="https://www.linkedin.com/in/aditya-devarshi/" target="_blank">πŸ”— LinkedIn</a></li>
<li><a href="https://github.com/devarshiadi" target="_blank">πŸ™ GitHub</a></li>
<li><a href="https://medium.com/@devarshia5" target="_blank">✍️ Medium</a></li>
</ul>
</div>
<div class="text-right">
<button id="closePopup" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Close
</button>
</div>
</div>
</div>
<script>
const fileInput = document.getElementById('fileInput');
const addImageBtn = document.getElementById('addImageBtn');
const thumbnails = document.getElementById('thumbnails');
const sendBtn = document.getElementById('sendBtn');
const resultArea = document.getElementById('resultArea');
// Array to hold selected image files.
let selectedFiles = [];
// Trigger file input when Add Image button is clicked.
addImageBtn.addEventListener('click', () => {
fileInput.click();
});
// Handle file selection.
fileInput.addEventListener('change', () => {
for (let file of fileInput.files) {
selectedFiles.push(file);
addThumbnail(file);
}
fileInput.value = ""; // reset input
});
// Function to add image thumbnail.
function addThumbnail(file) {
const reader = new FileReader();
reader.onload = function(e) {
const thumbContainer = document.createElement('div');
thumbContainer.classList.add('relative');
thumbContainer.innerHTML = `
<img src="${e.target.result}" alt="${file.name}" class="w-24 h-24 object-cover rounded border" />
<button class="removeBtn absolute -top-2 -right-2 bg-red-500 text-white rounded-full px-1 text-xs">x</button>
`;
thumbnails.appendChild(thumbContainer);
// Remove image on click.
thumbContainer.querySelector('.removeBtn').addEventListener('click', () => {
selectedFiles = selectedFiles.filter(f => f !== file);
thumbContainer.remove();
});
}
reader.readAsDataURL(file);
}
// Listen for paste events (Ctrl+V) to add images.
window.addEventListener('paste', (event) => {
const items = event.clipboardData.items;
for (let item of items) {
if (item.type.indexOf("image") !== -1) {
const file = item.getAsFile();
selectedFiles.push(file);
addThumbnail(file);
}
}
});
// Handle Send button click.
sendBtn.addEventListener('click', async () => {
if (selectedFiles.length === 0) {
alert("Please add at least one image.");
return;
}
const formData = new FormData();
selectedFiles.forEach(file => {
formData.append('files', file);
});
resultArea.innerHTML = `<p class="text-gray-500">Processing...</p>`;
try {
const response = await fetch('/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
if (response.ok && data.result) {
// Convert markdown result to HTML using marked.parse
resultArea.innerHTML = `<div class="bg-gray-200 p-4 rounded whitespace-pre-wrap">${marked.parse(data.result)}</div>`;
// Reset the UI.
selectedFiles = [];
thumbnails.innerHTML = "";
} else {
resultArea.innerHTML = `<p class="text-red-500">${data.detail || 'No result received.'}</p>`;
}
} catch (error) {
resultArea.innerHTML = `<p class="text-red-500">Error processing the images: ${error.message}</p>`;
}
});
// Show popup only if it hasn't been shown before
if (!localStorage.getItem('popupShown')) {
document.getElementById('popupCard').style.display = 'flex';
} else {
document.getElementById('popupCard').style.display = 'none';
}
document.getElementById('closePopup').addEventListener('click', function() {
document.getElementById('popupCard').style.display = 'none';
localStorage.setItem('popupShown', 'true');
});
</script>
</body>
</html>