btg-sandbox-image-scale/js/script.js
DJP 8be6a1ecab Initial commit: Topaz Labs Gigapixel Image Upscaler web application
- PHP-based web interface for image upscaling using Topaz Labs API
- Multiple image upload with batch processing support
- AI model selection (Standard V2, Low Resolution V2, CGI, etc.)
- Output resolution options from 2K to 8K
- Face enhancement feature
- Real-time job tracking and status monitoring
- Bulk download functionality
- Dark mode toggle
- Microsoft authentication integration
- Comprehensive README with installation instructions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 14:15:31 -04:00

217 lines
7.6 KiB
JavaScript
Executable file

const POLL_INTERVAL = 5000; // 5 seconds
document.addEventListener('DOMContentLoaded', function() {
loadJobHistory();
document.getElementById('uploadForm').addEventListener('submit', handleFormSubmit);
document.getElementById('bulkDownload').addEventListener('click', bulkDownload);
// Add event listener for file input change
document.querySelector('input[type="file"]').addEventListener('change', updateSelectedFiles);
addSelectAllButton();
});
function handleFormSubmit(e) {
e.preventDefault();
const formData = new FormData(this);
const files = formData.getAll('images[]');
files.forEach(file => {
const individualFormData = new FormData();
individualFormData.append('image', file);
individualFormData.append('output_height', formData.get('output_height'));
individualFormData.append('model', formData.get('model'));
individualFormData.append('face_enhancement', formData.get('face_enhancement'));
uploadFile(individualFormData);
});
}
function uploadFile(formData) {
fetch('process.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.process_id) {
addJobToList(data.process_id, formData.get('image').name);
pollJobStatus(data.process_id);
addToJobHistory(data.process_id, formData.get('image').name);
} else if (data.error) {
console.error('Error:', data.error);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function addJobToList(processId, fileName) {
const jobList = document.getElementById('jobList');
const jobItem = document.createElement('div');
jobItem.id = `job-${processId}`;
jobItem.innerHTML = `
<input type="checkbox" id="check-${processId}">
<label for="check-${processId}">${fileName} - Process ID: ${processId} - Status: Processing</label>
<button onclick="downloadJob('${processId}')" style="display:none;">Download</button>
`;
jobList.appendChild(jobItem);
if (!document.getElementById('selectAll')) {
addSelectAllButton();
}
document.getElementById('bulkDownload').style.display = 'block';
}
function pollJobStatus(processId) {
const pollInterval = setInterval(() => {
fetch(`status.php?process_id=${processId}`)
.then(response => response.json())
.then(data => {
updateJobStatus(processId, data.status, data.progress);
if (data.status === 'Completed') {
clearInterval(pollInterval);
updateJobHistory(processId, 'Completed');
}
})
.catch(error => {
console.error('Error:', error);
});
}, POLL_INTERVAL);
}
function updateJobStatus(processId, status, progress) {
const jobItem = document.getElementById(`job-${processId}`);
if (jobItem) {
const label = jobItem.querySelector('label');
label.textContent = `${label.textContent.split(' - ')[0]} - Status: ${status} - Progress: ${progress}%`;
if (status === 'Completed') {
jobItem.querySelector('button').style.display = 'inline-block';
}
}
}
function downloadJob(processId) {
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
const job = history.find(job => job.processId === processId);
if (job && (Date.now() - job.timestamp) <= (2 * 60 * 60 * 1000)) {
window.location.href = `download.php?process_id=${processId}`;
} else {
alert('This job is no longer available for download.');
// Remove the job from history if it's too old
history = history.filter(j => j.processId !== processId);
localStorage.setItem('jobHistory', JSON.stringify(history));
updateJobHistoryDisplay();
}
}
function addToJobHistory(processId, fileName) {
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
history.push({ processId, fileName, status: 'Processing', timestamp: Date.now() });
localStorage.setItem('jobHistory', JSON.stringify(history));
updateJobHistoryDisplay();
}
function updateJobHistory(processId, status) {
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
const index = history.findIndex(job => job.processId === processId);
if (index !== -1) {
history[index].status = status;
localStorage.setItem('jobHistory', JSON.stringify(history));
updateJobHistoryDisplay();
}
}
function loadJobHistory() {
updateJobHistoryDisplay();
}
function updateJobHistoryDisplay() {
cleanupOldJobs();
const historyContainer = document.getElementById('jobHistory');
const history = JSON.parse(localStorage.getItem('jobHistory')) || [];
let historyHTML = '<h2>Job History</h2>';
history.forEach(job => {
const date = new Date(job.timestamp);
historyHTML += `
<div>
${job.fileName} - ${job.status} - ${date.toLocaleString()}
${job.status === 'Completed' ?
`<button onclick="downloadJob('${job.processId}')">Download</button>` :
''}
</div>`;
});
historyHTML += '<button id="clearHistory">Clear History</button>';
historyContainer.innerHTML = historyHTML;
document.getElementById('clearHistory').addEventListener('click', clearJobHistory);
}
function clearJobHistory() {
localStorage.removeItem('jobHistory');
updateJobHistoryDisplay();
}
function bulkDownload() {
const checkedJobs = document.querySelectorAll('#jobList input[type="checkbox"]:checked');
checkedJobs.forEach(checkbox => {
const processId = checkbox.id.replace('check-', '');
downloadJob(processId);
});
}
function updateSelectedFiles() {
const fileInput = document.querySelector('input[type="file"]');
const fileList = document.getElementById('selectedFiles');
if (!fileList) {
const newFileList = document.createElement('div');
newFileList.id = 'selectedFiles';
fileInput.parentNode.insertBefore(newFileList, fileInput.nextSibling);
}
const files = fileInput.files;
let fileListHTML = '<strong>Selected Files:</strong><ul>';
for (let i = 0; i < files.length; i++) {
fileListHTML += `<li>${files[i].name}</li>`;
}
fileListHTML += '</ul>';
document.getElementById('selectedFiles').innerHTML = fileListHTML;
}
function addSelectAllButton() {
const jobList = document.getElementById('jobList');
if (!document.getElementById('selectAll')) {
const selectAllButton = document.createElement('button');
selectAllButton.id = 'selectAll';
selectAllButton.textContent = 'Select All';
selectAllButton.onclick = toggleSelectAll;
jobList.insertBefore(selectAllButton, jobList.firstChild);
}
}
function toggleSelectAll() {
const checkboxes = document.querySelectorAll('#jobList input[type="checkbox"]');
const selectAllButton = document.getElementById('selectAll');
const allChecked = Array.from(checkboxes).every(cb => cb.checked);
checkboxes.forEach(cb => cb.checked = !allChecked);
selectAllButton.textContent = allChecked ? 'Select All' : 'Deselect All';
}
function cleanupOldJobs() {
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
const twoHoursAgo = Date.now() - (2 * 60 * 60 * 1000); // 2 hours in milliseconds
history = history.filter(job => job.timestamp > twoHoursAgo);
localStorage.setItem('jobHistory', JSON.stringify(history));
}