msft-trns/js/script.js
2026-03-02 17:21:57 +00:00

309 lines
13 KiB
JavaScript

const POLL_INTERVAL = 5000; // 5 seconds
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM fully loaded and parsed');
loadJobHistory();
document.getElementById('uploadForm').addEventListener('submit', handleFormSubmit);
document.getElementById('bulkDownload').addEventListener('click', bulkDownload);
document.querySelector('input[type="file"]').addEventListener('change', updateSelectedFiles);
addSelectAllButton();
// Initialize dark mode
initDarkMode();
console.log('Microsoft Translator Document Translation initialized');
});
function handleFormSubmit(e) {
e.preventDefault();
console.log('Form submitted');
const formData = new FormData(this);
const files = formData.getAll('documents[]');
const targetLang = formData.get('target_lang');
console.log(`Number of files selected: ${files.length}`);
files.forEach((file, index) => {
console.log(`Processing file ${index + 1}: ${file.name}`);
const individualFormData = new FormData();
individualFormData.append('file', file);
individualFormData.append('source_lang', formData.get('source_lang'));
individualFormData.append('target_lang', targetLang);
individualFormData.append('formality', formData.get('formality'));
uploadFile(individualFormData);
});
}
function uploadFile(formData) {
console.log(`Uploading file: ${formData.get('file').name}`);
const endpoint = 'process.php';
console.log(`Using endpoint: ${endpoint}`);
fetch(endpoint, {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log(`Response from ${endpoint}:`, data);
if (data.document_id && data.document_key) {
console.log(`Document ID received: ${data.document_id}, Document Key: ${data.document_key}`);
addJobToList(data.document_id, formData.get('file').name);
pollJobStatus(data.document_id, data.document_key);
addToJobHistory(data.document_id, formData.get('file').name, data.document_key, formData.get('target_lang'));
} else if (data.error) {
console.error('Error:', data.error);
}
})
.catch(error => {
console.error('Error:', error);
});
}
function addJobToList(documentId, fileName) {
console.log(`Adding job to list: ${fileName} (ID: ${documentId})`);
const jobList = document.getElementById('jobList');
const jobItem = document.createElement('div');
jobItem.id = `job-${documentId}`;
jobItem.innerHTML = `
<input type="checkbox" id="check-${documentId}">
<label for="check-${documentId}">${fileName} - Document ID: ${documentId} - Status: Uploading</label>
<button onclick="downloadJob('${documentId}')" style="display:none;">Download</button>
`;
jobList.appendChild(jobItem);
if (!document.getElementById('selectAll')) {
addSelectAllButton();
}
document.getElementById('bulkDownload').style.display = 'block';
}
function pollJobStatus(documentId, documentKey) {
console.log(`Starting to poll status for document ID: ${documentId}`);
const statusEndpoint = 'status.php';
console.log(`Using status endpoint: ${statusEndpoint}`);
const pollInterval = setInterval(() => {
console.log(`Polling status for document ID: ${documentId}`);
fetch(`${statusEndpoint}?document_id=${documentId}&document_key=${documentKey}`)
.then(response => response.json())
.then(data => {
console.log(`Status response for document ID ${documentId}:`, data);
updateJobStatus(documentId, data.status);
if (data.status === 'done') {
console.log(`Job completed for document ID: ${documentId}`);
clearInterval(pollInterval);
// Update job history with completed status
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
const jobIndex = history.findIndex(job => job.documentId === documentId);
if (jobIndex !== -1) {
history[jobIndex].status = 'Completed';
localStorage.setItem('jobHistory', JSON.stringify(history));
updateJobHistoryDisplay();
}
}
})
.catch(error => {
console.error('Error polling status:', error);
});
}, POLL_INTERVAL);
}
function updateJobStatus(documentId, status) {
console.log(`Updating job status: ${documentId} - ${status}`);
const jobItem = document.getElementById(`job-${documentId}`);
if (jobItem) {
const label = jobItem.querySelector('label');
label.textContent = `${label.textContent.split(' - ')[0]} - Status: ${status}`;
if (status === 'done') {
jobItem.querySelector('button').style.display = 'inline-block';
}
}
}
function downloadJob(documentId) {
console.log(`Initiating download for document ID: ${documentId}`);
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
const job = history.find(job => job.documentId === documentId);
if (job && job.documentKey && job.fileName && job.targetLang) {
console.log(`Found job in history: ${JSON.stringify(job)}`);
const downloadUrl = `download.php?document_id=${documentId}&document_key=${job.documentKey}&original_filename=${encodeURIComponent(job.fileName)}&target_lang=${job.targetLang}`;
// Create a hidden iframe to trigger the download and webhook
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.src = downloadUrl;
// Remove the iframe after a short delay
setTimeout(() => {
document.body.removeChild(iframe);
}, 5000);
} else {
console.error(`Job not found in history or missing required information for document ID: ${documentId}`);
alert('This job is no longer available for download or is missing required information.');
updateJobHistoryDisplay();
}
}
function addToJobHistory(documentId, fileName, documentKey, targetLang) {
console.log(`Adding job to history: ${documentId}, ${fileName}, ${documentKey}, ${targetLang}`);
let history = JSON.parse(localStorage.getItem('jobHistory')) || [];
history.push({ documentId, fileName, documentKey, targetLang, status: 'Uploading', timestamp: Date.now() });
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.documentId}')">Download</button>` :
''}
</div>`;
});
// Add clear history button
if (history.length > 0) {
historyHTML += '<button id="clearHistory">Clear History</button>';
} else {
historyHTML += '<p>No translation jobs yet.</p>';
}
historyContainer.innerHTML = historyHTML;
if (history.length > 0) {
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 documentId = checkbox.id.replace('check-', '');
downloadJob(documentId);
});
}
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));
}
// Dark mode functionality
function initDarkMode() {
// Add dark mode toggle button
const darkModeToggle = document.createElement('button');
darkModeToggle.id = 'darkModeToggle';
darkModeToggle.className = 'dark-mode-toggle';
darkModeToggle.title = 'Toggle Dark Mode';
darkModeToggle.innerHTML = `
<span id="lightModeIcon">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
</svg>
</span>
<span id="darkModeIcon" style="display: none;">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/>
</svg>
</span>
`;
document.body.appendChild(darkModeToggle);
// Check for saved dark mode preference
const darkModeEnabled = localStorage.getItem('darkMode') === 'enabled';
if (darkModeEnabled) {
document.body.classList.add('dark-mode');
document.getElementById('lightModeIcon').style.display = 'none';
document.getElementById('darkModeIcon').style.display = 'block';
}
// Toggle dark mode when button is clicked
document.getElementById('darkModeToggle').addEventListener('click', function() {
document.body.classList.toggle('dark-mode');
// Save preference and toggle icons
if (document.body.classList.contains('dark-mode')) {
localStorage.setItem('darkMode', 'enabled');
document.getElementById('lightModeIcon').style.display = 'none';
document.getElementById('darkModeIcon').style.display = 'block';
} else {
localStorage.setItem('darkMode', 'disabled');
document.getElementById('lightModeIcon').style.display = 'block';
document.getElementById('darkModeIcon').style.display = 'none';
}
});
}