I was wondering if there was a way for users of public links to download images that are shown as image components in an app. Best would be a way to download several images as folder/zip through clicking a button and triggering an export event.
Create a REST query that returns the base64 encoded image data for the image you want to download.
Create a JavaScript query that triggers the REST query and then downloads the image data as a file.
Add a button to your app that triggers the JavaScript query when clicked.
Here is an example of a JavaScript query that you can use:
// Get the base64 encoded image data for the image you want to download.
const imgData = await api.trigger({
name: "GetImageBase64",
additionalScope: {
imageUrl: "https://example.com/image.jpg",
},
});
// Download the image data as a file.
utils.downloadFile({
base64Binary: imgData.base64Binary,
fileName: "image.jpg",
fileType: "image/jpeg",
});
You can also use the JSZip library to download multiple images as a folder/zip file. Here is an example of how to do that:
const zip = new JSZip();
// Add each image to the zip file.
for (const image of images) {
const imgData = await api.trigger({
name: "GetImageBase64",
additionalScope: {
imageUrl: image.url,
},
});
zip.folder("images").file(image.fileName, imgData.base64Binary, { base64: true });
}
// Generate the zip file and download it.
zip.generateAsync({ type: "base64" }).then(function (base64) {
utils.downloadFile({
base64Binary: base64,
fileName: "images.zip",
fileType: "application/zip",
});
});
Once you have created the REST query and JavaScript query, you can add a button to your app that triggers the JavaScript query when clicked. You can also add the button to a modal so that users can select which images they want to download before downloading them.
You may want to create a promise for each fetching and await all to fetch "in parallel". The zipping must done sequentially (with jszip at least). Retool has documented the promise use.
Makes quite a difference for large or multiple files.