Compare commits

..

2 commits

Author SHA1 Message Date
w
f826e27523 Add ZIP download functionality for card creation
- Included JSZip library for ZIP file creation.
- Added a button to download card data as a ZIP file containing the card image and JSON data.
- Implemented logic to generate safe filenames for the card image and JSON file.
2025-07-17 23:35:39 -03:00
w
3068b16a72 Sanitize file names for card image and JSON downloads to prevent invalid characters 2025-07-17 23:24:06 -03:00
2 changed files with 64 additions and 3 deletions

13
web/static/js/jszip.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -64,6 +64,7 @@
</div>
<script src="{{ url_for('static', filename='js/jszip.min.js') }}"></script>
<script>
const canvas = document.getElementById("cardCanvas");
const ctx = canvas.getContext("2d");
@ -221,13 +222,17 @@ function wrapText(text, x, y, maxWidth, lineHeight) {
// Download button
downloadBtn.addEventListener("click", () => {
// Sanitize file name
const safeName = (nameInput.value || "card").replace(/[^a-z0-9_\-]/gi, "_");
const safePack = (packInput.value || "pack").replace(/[^a-z0-9_\-]/gi, "_");
const fileName = `kemoverse_${safePack}_${safeName}.webp`;
const link = document.createElement("a");
link.download = "kemoverse-card.webp";
link.download = fileName;
link.href = canvas.toDataURL("image/webp", 0.95);
link.click();
});
// Create and place the JSON download button below the card download button
const jsonBtn = document.createElement("button");
jsonBtn.textContent = "Download Card Info";
jsonBtn.style.marginTop = "0.5rem";
@ -242,13 +247,56 @@ jsonBtn.onclick = () => {
artist: artistInput.value,
frame: frameSelect.value
};
const safeName = (nameInput.value || "card").replace(/[^a-z0-9_\-]/gi, "_");
const safePack = (packInput.value || "pack").replace(/[^a-z0-9_\-]/gi, "_");
const fileName = `kemoverse_${safePack}_${safeName}.json`;
const blob = new Blob([JSON.stringify(cardData, null, 2)], {type: "application/json"});
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "kemoverse-card.json";
link.download = fileName;
link.click();
};
// Place the button below the downloadBtn
downloadBtn.parentNode.insertBefore(jsonBtn, downloadBtn.nextSibling);
const zipBtn = document.createElement("button");
zipBtn.textContent = "Download Card ZIP";
zipBtn.style.marginTop = "0.5rem";
zipBtn.onclick = async () => {
const cardData = {
name: nameInput.value,
pack: packInput.value,
power: powerInput.value,
charm: charmInput.value,
wit: witInput.value,
flavor: flavorInput.value,
artist: artistInput.value,
frame: frameSelect.value
};
const safeName = (nameInput.value || "card").replace(/[^a-z0-9_\-]/gi, "_");
const safePack = (packInput.value || "pack").replace(/[^a-z0-9_\-]/gi, "_");
const imgFileName = `kemoverse_${safePack}_${safeName}.webp`;
const jsonFileName = `kemoverse_${safePack}_${safeName}.json`;
// Create ZIP
const zip = new JSZip();
// Add image
const imgData = canvas.toDataURL("image/webp", 0.95).split(',')[1];
zip.file(imgFileName, imgData, {base64: true});
// Add JSON
zip.file(jsonFileName, JSON.stringify(cardData, null, 2));
// Generate and download
const content = await zip.generateAsync({type: "blob"});
const link = document.createElement("a");
link.href = URL.createObjectURL(content);
link.download = `kemoverse_${safePack}_${safeName}.zip`;
link.click();
};
// Place the button below the downloadBtn
downloadBtn.parentNode.insertBefore(zipBtn, downloadBtn.nextSibling);
</script>
{% endblock %}