sourav520's picture
Update templates/compress.html
cfaec33 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PDF Compressor</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
:root {
--bg: #121212;
--card: #1e1e1e;
--text: #e0e0e0;
--accent: #0d6efd;
--accent-hover: #3b82f6;
--success: #28a745;
--error: #dc3545;
}
body {
font-family: "Segoe UI", Arial, sans-serif;
background: var(--bg);
margin: 0;
padding: 15px;
color: var(--text);
}
.container {
max-width: 600px;
margin: auto;
background: var(--card);
padding: 20px;
border-radius: 14px;
box-shadow: 0 6px 20px rgba(0,0,0,0.6);
}
h2 {
text-align: center;
margin-bottom: 20px;
color: var(--text);
}
/* Drop Area */
.drop-area {
display: block;
width: 100%;
border: 2px dashed var(--accent);
border-radius: 12px;
padding: 15px 20px;
text-align: center;
color: #bbb;
transition: background 0.3s, border 0.3s, box-shadow 0.3s;
cursor: pointer;
font-size: 15px;
box-sizing: border-box;
}
.drop-area:hover {
border-color: var(--accent-hover);
box-shadow: 0 0 12px rgba(13,110,253,0.4);
}
.drop-area.dragover {
background: rgba(13, 110, 253, 0.1);
border-color: var(--accent-hover);
box-shadow: 0 0 18px rgba(13,110,253,0.6);
}
input[type="file"] {
display: none;
}
/* Preview */
.preview {
margin-top: 15px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.preview canvas {
width: 130px;
border: 1px solid #333;
border-radius: 8px;
margin-bottom: 10px;
}
.file-info {
font-size: 14px;
color: #aaa;
}
/* Form elements */
select, input[type="number"], button {
margin-top: 12px;
padding: 14px;
width: 100%;
border-radius: 10px;
border: 1px solid #333;
font-size: 15px;
background: #2a2a2a;
color: var(--text);
box-sizing: border-box;
}
select:focus, input:focus {
outline: none;
border-color: var(--accent);
}
button {
background: var(--accent);
font-weight: 600;
cursor: pointer;
border: none;
transition: background 0.3s, transform 0.2s;
}
button:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
/* Status & Download */
#status {
text-align: center;
margin-top: 15px;
font-weight: 500;
font-size: 15px;
}
#status.success { color: var(--success); }
#status.error { color: var(--error); }
#downloadLink {
display: none;
text-align: center;
margin: 12px auto 0 auto;
text-decoration: none;
color: white;
background: var(--success);
padding: 12px 20px;
border-radius: 10px;
font-weight: 600;
transition: background 0.3s;
width: fit-content;
}
#downloadLink:hover { background: #218838; }
/* Mobile tweaks */
@media (max-width: 600px) {
.container {
padding: 15px;
}
h2 { font-size: 20px; }
button, select, input[type="number"] {
font-size: 14px;
padding: 12px;
}
.preview canvas {
width: 100px;
}
}
</style>
</head>
<body>
<div class="container">
<h2>📄 PDF Compressor</h2>
<label for="fileInput" class="drop-area" id="dropArea">
<p>🚀 Drag & Drop your PDF here<br>or <strong>Tap to Select</strong></p>
</label>
<input type="file" id="fileInput" name="pdf" accept="application/pdf" required>
<div class="preview" id="preview"></div>
<form style="display: none;" id="uploadForm" enctype="multipart/form-data">
<label>Compression Type:</label>
<select name="preset" id="preset">
<option value="low">Low (10%) Compression</option>
<option value="medium">Medium (20%) Compression</option>
<option value="high">High (%70) Compression</option>
<option value="custom" selected>Custom Size</option>
</select>
<div id="customSizeDiv" style="display:block;">
<label>Target Size (KB):</label>
<input type="number" name="target_kb" placeholder="e.g. 500 (for 500KB)">
</div>
<button type="submit">Compress</button>
</form>
<p id="status"></p>
<a id="downloadLink" href="#">✔️Save Compressed PDF</a>
</div>
<!-- PDF.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
<script>
const fileInput = document.getElementById("fileInput");
const preview = document.getElementById("preview");
let sizeKB_temp;
dropArea.addEventListener("dragover", (e) => {
e.preventDefault();
dropArea.classList.add("dragover");
});
dropArea.addEventListener("dragleave", () => dropArea.classList.remove("dragover"));
dropArea.addEventListener("drop", (e) => {
e.preventDefault();
dropArea.classList.remove("dragover");
if (e.dataTransfer.files.length) {
fileInput.files = e.dataTransfer.files;
showPreview(fileInput.files[0]);
}
});
fileInput.addEventListener("change", () => {
if (fileInput.files.length) {
const file = fileInput.files[0]; // ✅ correct way to get the file
const ext = file.name.split(".").pop().toLowerCase();
if (ext !== "pdf" || file.type !== "application/pdf") {
alert("❌ Only PDF files are allowed!");
fileInput.value = "";
return;
}
const sizeKB = Math.round(file.size / 1024);
document.querySelector("#preset option[value='low']").textContent = `Low (~ ${Math.round(sizeKB-(sizeKB * 0.1))}KB)`;
document.querySelector("#preset option[value='medium']").textContent = `Medium (~ ${Math.round(sizeKB-(sizeKB * 0.3))}KB)`;
document.querySelector("#preset option[value='high']").textContent = `High (~ ${Math.round(sizeKB-(sizeKB * 0.6))}KB)`;
document.getElementById("uploadForm").style.display = "block";
showPreview(fileInput.files[0]);
}
});
// Preview PDF
async function showPreview(file) {
preview.innerHTML = "";
if (file && file.type === "application/pdf") {
let sizeKB = (file.size / 1024).toFixed(2);
sizeKB_temp = sizeKB;
const fileInfo = document.createElement("p");
fileInfo.className = "file-info";
fileInfo.innerText = `📂 ${file.name}${sizeKB} KB`;
preview.appendChild(fileInfo);
const fileReader = new FileReader();
fileReader.onload = async function() {
const typedarray = new Uint8Array(this.result);
const pdf = await pdfjsLib.getDocument(typedarray).promise;
const page = await pdf.getPage(1);
const viewport = page.getViewport({ scale: 0.25 });
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.height = viewport.height;
canvas.width = viewport.width;
await page.render({ canvasContext: context, viewport }).promise;
preview.insertBefore(canvas, fileInfo);
};
fileReader.readAsArrayBuffer(file);
}
}
// Custom size toggle
document.getElementById("preset").addEventListener("change", function() {
document.getElementById("customSizeDiv").style.display =
this.value === "custom" ? "block" : "none";
});
// Form submit
document.getElementById("uploadForm").addEventListener("submit", async function(e) {
e.preventDefault();
const statusEl = document.getElementById("status");
statusEl.innerText = "⏳ Compressing...";
statusEl.className = "";
document.getElementById("downloadLink").style.display = "none";
let formData = new FormData();
if (fileInput.files.length) {
formData.append("pdf", fileInput.files[0]);
}
const preset_value = document.getElementById("preset").value;
let targetInput = document.querySelector("input[name='target_kb']");
switch(preset_value){
case "low":
var temp = (sizeKB_temp - (sizeKB_temp * 0.1));
targetInput.value = Math.ceil(temp);
break;
case "medium":
var temp = (sizeKB_temp - (sizeKB_temp * 0.3));
targetInput.value = Math.ceil(temp);
break;
case "high":
var temp = (sizeKB_temp - (sizeKB_temp * 0.6));
targetInput.value = Math.ceil(temp);
break;
}
formData.append("preset", preset_value);
if (targetInput && targetInput.value) {
formData.append("target_kb", targetInput.value);
console.log(targetInput.value)
}
let res = await fetch("/compress", { method: "POST", body: formData });
let data = await res.json();
if (data.success) {
statusEl.innerText = "✅ Compression successful!";
statusEl.className = "success";
let link = document.getElementById("downloadLink");
link.href = "/download/" + data.filename;
link.style.display = "block";
} else {
statusEl.innerText = "❌ Compression failed!";
statusEl.className = "error";
}
});
</script>
</body>
</html>