JS and css cleanup

This commit is contained in:
Anthony Stirling
2023-06-02 20:15:10 +01:00
parent 7bdb2615d4
commit 45b3e0aa6a
14 changed files with 669 additions and 644 deletions

View File

@@ -34,84 +34,7 @@
<script src="js/tab-container.js"></script>
<script>
var toggleCount = 0;
var lastToggleTime = Date.now();
function toggleDarkMode() {
var currentTime = Date.now();
if (currentTime - lastToggleTime < 1000) {
toggleCount++;
} else {
toggleCount = 1;
}
lastToggleTime = currentTime;
var lightModeStyles = document.getElementById("light-mode-styles");
var darkModeStyles = document.getElementById("dark-mode-styles");
var rainbowModeStyles = document.getElementById("rainbow-mode-styles");
var darkModeIcon = document.getElementById("dark-mode-icon");
if (toggleCount >= 18) {
localStorage.setItem("dark-mode", "rainbow");
lightModeStyles.disabled = true;
darkModeStyles.disabled = true;
rainbowModeStyles.disabled = false;
darkModeIcon.src = "rainbow.svg";
} else if (localStorage.getItem("dark-mode") == "on") {
localStorage.setItem("dark-mode", "off");
lightModeStyles.disabled = false;
darkModeStyles.disabled = true;
rainbowModeStyles.disabled = true;
darkModeIcon.src = "sun.svg";
} else {
localStorage.setItem("dark-mode", "on");
lightModeStyles.disabled = true;
darkModeStyles.disabled = false;
rainbowModeStyles.disabled = true;
darkModeIcon.src = "moon.svg";
}
}
document.addEventListener("DOMContentLoaded", function () {
var lightModeStyles = document.getElementById("light-mode-styles");
var darkModeStyles = document.getElementById("dark-mode-styles");
var rainbowModeStyles = document.getElementById("rainbow-mode-styles");
var darkModeIcon = document.getElementById("dark-mode-icon");
if (localStorage.getItem("dark-mode") == "on") {
lightModeStyles.disabled = true;
darkModeStyles.disabled = false;
rainbowModeStyles.disabled = true;
darkModeIcon.src = "moon.svg";
} else if (localStorage.getItem("dark-mode") == "off") {
lightModeStyles.disabled = false;
darkModeStyles.disabled = true;
rainbowModeStyles.disabled = true;
darkModeIcon.src = "sun.svg";
} else if (localStorage.getItem("dark-mode") == "rainbow") {
lightModeStyles.disabled = true;
darkModeStyles.disabled = true;
rainbowModeStyles.disabled = false;
darkModeIcon.src = "rainbow.svg";
} else {
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
darkModeStyles.disabled = false;
rainbowModeStyles.disabled = true;
darkModeIcon.src = "moon.svg";
} else {
darkModeStyles.disabled = true;
rainbowModeStyles.disabled = true;
darkModeIcon.src = "sun.svg";
}
}
document.getElementById("dark-mode-toggle").addEventListener("click", function (event) {
event.preventDefault();
toggleDarkMode();
});
});
</script>
<script src="js/darkmode.js"></script>
</head>
@@ -168,214 +91,7 @@ document.addEventListener("DOMContentLoaded", function () {
</th:block>
<th:block th:fragment="fileSelector(name, multiple)" th:with="accept=${accept} ?: '*/*', inputText=${inputText} ?: #{pdfPrompt}, remoteCall=${remoteCall} ?: 'true', notRequired=${notRequired} ?: false">
<script>
function showErrorBanner(message, stackTrace) {
const errorContainer = document.getElementById("errorContainer");
errorContainer.style.display = "block"; // Display the banner
document.querySelector("#errorContainer .alert-heading").textContent = "Error";
document.querySelector("#errorContainer p").textContent = message;
document.querySelector("#traceContent").textContent = stackTrace;
}
$(document).ready(function () {
$('form').submit(async function (event) {
event.preventDefault();
const url = this.action;
const files = $('#fileInput-input')[0].files;
const formData = new FormData(this);
const override = $('#override').val() || '';
$('#submitBtn').text('Processing...');
try {
if (override === 'multi' || files.length > 1 && override !== 'single') {
await submitMultiPdfForm(url, files);
} else {
const downloadDetails = await handleSingleDownload(url, formData);
// Determine the download option from localStorage
const downloadOption = localStorage.getItem('downloadOption');
// Handle the download action according to the selected option
handleDownloadAction(downloadOption, downloadDetails.blob, downloadDetails.filename);
}
$('#submitBtn').text('Submit');
} catch (error) {
handleDownloadError(error);
$('#submitBtn').text('Submit');
}
});
});
function handleDownloadAction(downloadOption, blob, filename) {
const url = URL.createObjectURL(blob);
switch (downloadOption) {
case 'sameWindow':
// Open the file in the same window
window.location.href = url;
break;
case 'newWindow':
// Open the file in a new window
window.open(url, '_blank');
break;
default:
// Download the file
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
break;
}
}
async function handleSingleDownload(url, formData) {
const response = await fetch(url, {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
} else {
const blob = await response.blob();
const filename = getFilenameFromContentDisposition(response.headers.get('Content-Disposition'));
return { blob, filename };
}
}
function getFilenameFromContentDisposition(contentDisposition) {
let filename;
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, ''));
} else {
// If the Content-Disposition header is not present or does not contain the filename, use a default filename
filename = 'download';
}
return filename;
}
async function handlePdfOrImageResponse(response, filename) {
const downloadOption = localStorage.getItem('downloadOption');
const blob = await response.blob();
const url = URL.createObjectURL(blob);
if (downloadOption === 'sameWindow') {
window.location.href = url;
} else if (downloadOption === 'newWindow') {
window.open(url, '_blank');
} else {
downloadFile(url, filename);
}
}
async function handleJsonResponse(response) {
const json = await response.json();
const errorMessage = JSON.stringify(json, null, 2);
if(errorMessage.toLowerCase().includes('the password is incorrect') || errorMessage.toLowerCase().includes('Password is not provided')){
alert('[[#{error.pdfPassword}]]');
} else {
showErrorBanner(json.error + ':' + json.message, json.trace);
}
}
async function handleOtherResponse(response, filename) {
const blob = await response.blob();
const url = URL.createObjectURL(blob);
downloadFile(url, filename);
}
function handleDownloadError(error) {
const errorMessage = error.message;
showErrorBanner(errorMessage);
}
let urls = []; // An array to hold all the URLs
function downloadFile(blob, filename) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
urls.push(url); // Store the URL so it doesn't get garbage collected too soon
}
async function submitMultiPdfForm(url, files) {
const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
const zipFiles = files.length > zipThreshold;
let jszip = null;
let progressBar = $('#progressBar');
progressBar.css('width', '0%');
progressBar.attr('aria-valuenow', 0);
progressBar.attr('aria-valuemax', Array.from(files).length);
if (zipFiles) {
jszip = new JSZip();
}
// Get existing form data
let formData = new FormData($('form')[0]);
formData.delete('fileInput');
const CONCURRENCY_LIMIT = 8;
const chunks = [];
for (let i = 0; i < Array.from(files).length; i += CONCURRENCY_LIMIT) {
chunks.push(Array.from(files).slice(i, i + CONCURRENCY_LIMIT));
}
for (const chunk of chunks) {
const promises = chunk.map(async file => {
let fileFormData = new FormData();
fileFormData.append('fileInput', file);
// Add other form data
for (let pair of formData.entries()) {
fileFormData.append(pair[0], pair[1]);
}
try {
const downloadDetails = await handleSingleDownload(url, fileFormData);
if (zipFiles) {
jszip.file(downloadDetails.filename, downloadDetails.blob);
} else {
downloadFile(downloadDetails.blob, downloadDetails.filename);
}
updateProgressBar(progressBar, Array.from(files).length);
} catch (error) {
handleDownloadError(error);
}
});
await Promise.all(promises);
}
if (zipFiles) {
try {
const content = await jszip.generateAsync({ type: "blob" });
downloadFile(content, "files.zip");
} catch (error) {
console.error('Error generating ZIP file: ' + error);
}
}
}
function updateProgressBar(progressBar, files) {
let progress = ((progressBar.attr('aria-valuenow') / files.length) * 100) + (100 / files.length);
progressBar.css('width', progress + '%');
progressBar.attr('aria-valuenow', parseInt(progressBar.attr('aria-valuenow')) + 1);
}
window.addEventListener('unload', () => {
for (const url of urls) {
URL.revokeObjectURL(url);
}
});
</script>
<script src="js/downloader.js"></script>
<div class="custom-file-chooser">
<div class="custom-file">
@@ -394,65 +110,12 @@ document.addEventListener("DOMContentLoaded", function () {
<button type="button" class="btn btn-primary" id="show-game-btn" style="display:none;">Bored waiting?</button>
<script th:inline="javascript">
document.addEventListener('DOMContentLoaded', function () {
const fileInput = document.getElementById([[${name+"-input"}]]);
// Prevent default behavior for drag events
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
fileInput.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// Add drop event listener
fileInput.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
fileInput.files = files;
handleFileInputChange(fileInput)
}
});
$([[${"#"+name+"-input"}]]).on("change", function() {
handleFileInputChange(this);
});
function handleFileInputChange(inputElement) {
const files = $(inputElement).get(0).files;
const fileNames = Array.from(files).map(f => f.name);
const selectedFilesContainer = $(inputElement).siblings(".selected-files");
selectedFilesContainer.empty();
fileNames.forEach(fileName => {
selectedFilesContainer.append("<div>" + fileName + "</div>");
});
console.log("fileNames.length=" + fileNames.length)
if (fileNames.length === 1) {
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
} else if (fileNames.length > 1) {
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames.length + " " + [[#{filesSelected}]]);
} else {
$(inputElement).siblings(".custom-file-label").addClass("selected").html([[#{pdfPrompt}]]);
}
}
<script th:inline="javascript">
const elementID = /*[[${name+"-input"}]]*/ '';
const filesSelected = /*[[#{filesSelected}]]*/ '';
const pdfPrompt = /*[[#{pdfPrompt}]]*/ '';
</script>
<style>
.custom-file-label {
padding-right: 90px;
}
.selected-files {
margin-top: 10px;
max-height: 150px;
overflow-y: auto;
white-space: pre-wrap;
}
</style>
<script src="js/fileInput.js"></script>
<link rel="stylesheet" href="css/fileSelect.css">
</th:block>