diff --git a/core/static/bundled/user/pictures-index.js b/core/static/bundled/user/pictures-index.js deleted file mode 100644 index 5ee95b90..00000000 --- a/core/static/bundled/user/pictures-index.js +++ /dev/null @@ -1,110 +0,0 @@ -import { paginated } from "#core:utils/api"; -import { HttpReader, ZipWriter } from "@zip.js/zip.js"; -import { showSaveFilePicker } from "native-file-system-adapter"; -import { picturesFetchPictures } from "#openapi"; - -/** - * @typedef UserProfile - * @property {number} id - * @property {string} first_name - * @property {string} last_name - * @property {string} nick_name - * @property {string} display_name - * @property {string} profile_url - * @property {string} profile_pict - */ -/** - * @typedef Picture - * @property {number} id - * @property {string} name - * @property {number} size - * @property {string} date - * @property {UserProfile} owner - * @property {string} full_size_url - * @property {string} compressed_url - * @property {string} thumb_url - * @property {string} album - * @property {boolean} is_moderated - * @property {boolean} asked_for_removal - */ - -/** - * @typedef PicturePageConfig - * @property {number} userId Id of the user to get the pictures from (optional if albumId defined) - * @property {number} albumId Id of the album to get the pictures from (optinal if userId defined) - **/ - -/** - * Load user picture page with a nice download bar - * @param {PicturePageConfig} config - **/ -window.loadPicturePage = (config) => { - document.addEventListener("alpine:init", () => { - Alpine.data("user_pictures", () => ({ - isDownloading: false, - loading: true, - pictures: [], - albums: {}, - - async init() { - let query = {}; - - if (config.userId) { - // biome-ignore lint/style/useNamingConvention: api is in snake_case - query = { users_identified: [config.userId] }; - } else { - // biome-ignore lint/style/useNamingConvention: api is in snake_case - query = { album_id: config.albumId }; - } - this.pictures = await paginated(picturesFetchPictures, { - query, - }); - this.albums = this.pictures.reduce((acc, picture) => { - if (!acc[picture.album]) { - acc[picture.album] = []; - } - acc[picture.album].push(picture); - return acc; - }, {}); - this.loading = false; - }, - - async downloadZip() { - this.isDownloading = true; - const bar = this.$refs.progress; - bar.value = 0; - bar.max = this.pictures.length; - - const incrementProgressBar = () => { - bar.value++; - }; - - const fileHandle = await showSaveFilePicker({ - _preferPolyfill: false, - suggestedName: interpolate( - gettext("pictures.%(extension)s"), - { extension: "zip" }, - true, - ), - types: {}, - excludeAcceptAllOption: false, - }); - const zipWriter = new ZipWriter(await fileHandle.createWritable()); - - await Promise.all( - this.pictures.map((p) => { - const imgName = `${p.album}/IMG_${p.date.replaceAll(/[:\-]/g, "_")}${p.name.slice(p.name.lastIndexOf("."))}`; - return zipWriter.add(imgName, new HttpReader(p.full_size_url), { - level: 9, - lastModDate: new Date(p.date), - onstart: incrementProgressBar, - }); - }), - ); - - await zipWriter.close(); - this.isDownloading = false; - }, - })); - }); -}; diff --git a/core/static/bundled/user/pictures-index.ts b/core/static/bundled/user/pictures-index.ts new file mode 100644 index 00000000..34140323 --- /dev/null +++ b/core/static/bundled/user/pictures-index.ts @@ -0,0 +1,111 @@ +import { paginated } from "#core:utils/api"; +import { HttpReader, ZipWriter } from "@zip.js/zip.js"; +import { showSaveFilePicker } from "native-file-system-adapter"; +import { picturesFetchPictures } from "#openapi"; + +/** + * @typedef UserProfile + * @property {number} id + * @property {string} first_name + * @property {string} last_name + * @property {string} nick_name + * @property {string} display_name + * @property {string} profile_url + * @property {string} profile_pict + */ +/** + * @typedef Picture + * @property {number} id + * @property {string} name + * @property {number} size + * @property {string} date + * @property {UserProfile} owner + * @property {string} full_size_url + * @property {string} compressed_url + * @property {string} thumb_url + * @property {string} album + * @property {boolean} is_moderated + * @property {boolean} asked_for_removal + */ + +/** + * @typedef PicturePageConfig + * @property {number} userId Id of the user to get the pictures from (optional if albumId defined) + * @property {number} albumId Id of the album to get the pictures from (optinal if userId defined) + **/ + +/** + * Load user picture page with a nice download bar + * @param {PicturePageConfig} config + **/ + +interface PagePictureConfig { + userId?: number; + albumId?: number; +} + +document.addEventListener("alpine:init", () => { + Alpine.data("user_pictures", (config: PagePictureConfig) => ({ + isDownloading: false, + loading: true, + pictures: [], + albums: {}, + + async init() { + const query: Record = {}; + + if (config.userId) { + query.user_identified = config.userId; + } else { + query.album_id = config.albumId; + } + this.pictures = await paginated(picturesFetchPictures, { query: query }); + + this.albums = this.pictures.reduce((acc, picture) => { + if (!acc[picture.album]) { + acc[picture.album] = []; + } + acc[picture.album].push(picture); + return acc; + }, {}); + this.loading = false; + }, + + async downloadZip() { + this.isDownloading = true; + const bar = this.$refs.progress; + bar.value = 0; + bar.max = this.pictures.length; + + const incrementProgressBar = () => { + bar.value++; + }; + + const fileHandle = await showSaveFilePicker({ + _preferPolyfill: false, + suggestedName: interpolate( + gettext("pictures.%(extension)s"), + { extension: "zip" }, + true, + ), + types: {}, + excludeAcceptAllOption: false, + }); + const zipWriter = new ZipWriter(await fileHandle.createWritable()); + + await Promise.all( + this.pictures.map((p) => { + const imgName = `${p.album}/IMG_${p.date.replaceAll(/[:\-]/g, "_")}${p.name.slice(p.name.lastIndexOf("."))}`; + return zipWriter.add(imgName, new HttpReader(p.full_size_url), { + level: 9, + lastModDate: new Date(p.date), + onstart: incrementProgressBar, + }); + }), + ); + + await zipWriter.close(); + this.isDownloading = false; + }, + })); +}); diff --git a/core/templates/core/user_pictures.jinja b/core/templates/core/user_pictures.jinja index 7f1d6f0b..e5fd36ce 100644 --- a/core/templates/core/user_pictures.jinja +++ b/core/templates/core/user_pictures.jinja @@ -6,7 +6,7 @@ {%- endblock -%} {% block additional_js %} - + {% endblock %} {% block title %} diff --git a/sas/templates/sas/album.jinja b/sas/templates/sas/album.jinja index d1b32e95..f1fc565d 100644 --- a/sas/templates/sas/album.jinja +++ b/sas/templates/sas/album.jinja @@ -8,7 +8,7 @@ {%- block additional_js -%} - + {%- endblock -%} {% block title %} @@ -64,7 +64,7 @@
{% endif %} -
+
{{ download_button() }}