add some alpine to picture download

This commit is contained in:
thomas girod 2024-07-30 19:23:48 +02:00
parent ffa3936878
commit 91344741a5

View File

@ -10,6 +10,7 @@
window.showSaveFilePicker = showSaveFilePicker; /* Export function to normal javascript */ window.showSaveFilePicker = showSaveFilePicker; /* Export function to normal javascript */
</script> </script>
<script defer type="text/javascript" src="{{ static('core/js/zipjs/zip-fs-full.min.js') }}"></script> <script defer type="text/javascript" src="{{ static('core/js/zipjs/zip-fs-full.min.js') }}"></script>
<script defer src="{{ static("core/js/alpinejs.min.js") }}"></script>
{% endblock %} {% endblock %}
{% block title %} {% block title %}
@ -19,8 +20,15 @@
{% block content %} {% block content %}
<main> <main>
{% if can_edit(profile, user) %} {% if can_edit(profile, user) %}
<button disabled id="download" onclick="download('{{ url('api:pictures') }}?users_identified={{ object.id }}')">{% trans %}Download all my pictures{% endtrans %}</button> <div x-data="picture_download" x-cloak>
<progress id="download_progress" max="100" hidden></progress> <button
:disabled="in_progress"
@click="download('{{ url("api:pictures") }}?users_identified={{ object.id }}')"
>
{% trans %}Download all my pictures{% endtrans %}
</button>
<progress x-ref="progress" x-show="in_progress"></progress>
</div>
{% endif %} {% endif %}
{% for album, pictures in albums|items %} {% for album, pictures in albums|items %}
<h4>{{ album }}</h4> <h4>{{ album }}</h4>
@ -51,50 +59,58 @@
</div> </div>
<br> <br>
{% endfor %} {% endfor %}
</main>
{% endblock %}
{% block script %}
{{ super() }}
<script> <script>
document.addEventListener("DOMContentLoaded", () => { /**
document.getElementById("download").disabled = false; * @typedef Picture
}); * @property {number} id
async function download(url) { * @property {string} name
* @property {number} size
* @property {string} date
* @property {Object} author
* @property {string} full_size_url
* @property {string} compressed_url
* @property {string} thumb_url
*/
let pictures = await (await fetch(url)).json(); document.addEventListener("alpine:init", () => {
Alpine.data("picture_download", () => ({
in_progress: false,
let progressBar = document.getElementById("download_progress"); async download(url) {
let button = document.getElementById("download"); this.in_progress = true;
let picturesDownloaded = 0; const bar = this.$refs.progress;
bar.value = 0;
button.disabled = true; /** @type Picture[] */
progressBar.value = picturesDownloaded; const pictures = await (await fetch(url)).json();
progressBar.hidden = false; bar.max = pictures.length;
let fileHandle = await window.showSaveFilePicker({ const fileHandle = await window.showSaveFilePicker({
_preferPolyfill: false, _preferPolyfill: false,
suggestedName: "{%- trans -%} pictures {%- endtrans -%}.zip", suggestedName: "{%- trans -%} pictures {%- endtrans -%}.zip",
types: {}, types: {},
excludeAcceptAllOption: false, excludeAcceptAllOption: false,
}) })
let writeStream = await fileHandle.createWritable(); const zipWriter = new zip.ZipWriter(await fileHandle.createWritable());
let zipWriter = new zip.ZipWriter(writeStream); await Promise.all(pictures.map(p => {
const img_name = "IMG_" + p.date.replaceAll(/[:\-]/g, "_") + p.name.slice(p.name.lastIndexOf("."));
async function progress() { return zipWriter.add(
progressBar.value = picturesDownloaded++ * 100 / (pictures.length - 1); img_name,
} new zip.HttpReader(p.full_size_url),
{level: 9, lastModDate: new Date(p.date), onstart: () => bar.value += 1}
await Promise.all(pictures.map(picture => );
zipWriter.add( }))
"IMG_" + picture.date.replaceAll(":", "_").replaceAll("-", "_") + picture.name.slice(picture.name.lastIndexOf(".")),
new zip.HttpReader(picture.full_size_url),
{ level: 9, lastModDate: new Date(picture.date), onstart: progress }
)
)
)
await zipWriter.close(); await zipWriter.close();
this.in_progress = false;
button.disabled = false;
progressBar.hidden = true;
} }
}))
});
</script> </script>
</main>
{% endblock %} {% endblock %}