more tweaks

This commit is contained in:
gapato 2026-06-08 21:04:10 +02:00
commit b3c7be655e
3 changed files with 42 additions and 38 deletions

View file

@ -128,7 +128,7 @@ async function getApplicants() {
function sanitizeZipPathSegment(value, fallback = "unnamed") {
const sanitized = String(value ?? "")
.replace(/[\/\\:*?"<>| ]/g, "_")
.replace(/[\/\\:*?"<>|]/g, "_")
.trim()
return sanitized === "" ? fallback : sanitized
@ -287,46 +287,18 @@ function getFflate() {
}
async function createZipBlob(archiveEntries) {
const { Zip, ZipPassThrough } = getFflate()
return new Promise((resolve, reject) => {
const chunks = []
const zip = new Zip()
let settled = false
zip.ondata = (error, chunk, final) => {
if (settled) {
return
}
fflate.zip(archiveEntries, { level: 0, consume: true }, (error, data) => {
if (error != null) {
settled = true
reject(error)
return
}
chunks.push(chunk)
if (final) {
settled = true
resolve(new Blob(chunks, { type: "application/zip" }))
}
}
try {
Object.entries(archiveEntries).forEach(([path, bytes]) => {
const file = new ZipPassThrough(path)
zip.add(file)
file.push(bytes, true)
})
zip.end()
} catch (error) {
settled = true
reject(error)
}
resolve(data)
})
})
.then((archiveBytes) => {
return new Blob([archiveBytes], { type: "application/zip" })
})
}
function downloadBlob(blob, fileName) {
@ -378,6 +350,7 @@ function createProgressDialog() {
const size = document.createElement("p")
const actions = document.createElement("div")
const closeButton = document.createElement("button")
const downloadButton = document.createElement("button")
const entries = new Map()
const progress = new Map()
const startTime = Date.now()
@ -406,6 +379,12 @@ function createProgressDialog() {
size.textContent = `Downloaded size: ${formatMegabytes(totalDownloadedBytes)}`
}
downloadButton.type = "button"
downloadButton.id = "download-button"
downloadButton.textContent = "Download"
downloadButton.disabled = true
downloadButton.classList.add("ripper-hidden")
closeButton.type = "button"
closeButton.textContent = "Close"
closeButton.disabled = true
@ -420,6 +399,7 @@ function createProgressDialog() {
}
})
actions.append(downloadButton)
actions.append(closeButton)
summary.append(elapsed, downloaded, size)
dialog.append(title, status, list, summary, actions)
@ -488,6 +468,7 @@ function createProgressDialog() {
// Main export flow: fetch applicant data, download files, then assemble the ZIP.
function rip(event) {
Notification.requestPermission()
const btn = event.target;
const progressDialog = createProgressDialog()
btn.textContent = "working ..."
@ -549,13 +530,20 @@ function rip(event) {
archiveEntries["fflate.min.js"] = viewerFflateSource
console.log("Generating zip archive...")
return createZipBlob(archiveEntries)
createZipBlob(archiveEntries)
.then((zipBlob) => {
console.log("Zip archive is ready.")
if (Notification.permission == "granted") {
new Notification("EPAS Ripper", { body: `Zip archive for job offer ${aid} is ready for download` })
}
progressDialog.setStatus("Download ready.")
downloadBlob(zipBlob, `procedure_${aid}.zip`)
btn.textContent = "done"
const downloadButton = document.querySelector("#download-button")
downloadButton.addEventListener("click", () => {
downloadBlob(zipBlob, `procedure_${aid}.zip`)
})
downloadButton.classList.remove("ripper-hidden")
downloadButton.disabled = false
})
})