From ccbd550ba1d38a9bf2551450c16927da53da44e5 Mon Sep 17 00:00:00 2001 From: Alexander Saltykov Date: Wed, 26 Jul 2023 08:43:20 +0300 Subject: [PATCH] Adds multiple albums selection Signed-off-by: Alexander Saltykov --- src/components/AlbumsList.vue | 2 +- src/components/modal/AddToAlbumModal.vue | 35 +++++++--- src/components/modal/AlbumPicker.vue | 89 ++++++++++++++++++++---- 3 files changed, 100 insertions(+), 26 deletions(-) diff --git a/src/components/AlbumsList.vue b/src/components/AlbumsList.vue index 37bab0b0..3c2874a0 100644 --- a/src/components/AlbumsList.vue +++ b/src/components/AlbumsList.vue @@ -33,7 +33,7 @@ {{ t('memories', 'Add to album') }} - + diff --git a/src/components/modal/AddToAlbumModal.vue b/src/components/modal/AddToAlbumModal.vue index 502dd4f6..aa6673d9 100644 --- a/src/components/modal/AddToAlbumModal.vue +++ b/src/components/modal/AddToAlbumModal.vue @@ -5,7 +5,7 @@
- +
@@ -60,19 +60,32 @@ export default defineComponent({ this.$emit('close'); }, - async selectAlbum(album: IAlbum) { + async selectAlbums(albums: IAlbum[]) { if (this.processing) return; + const processed = new Set(); + const photosDone = new Set(); - const name = album.name || album.album_id.toString(); - const gen = dav.addToAlbum(album.user, name, this.photos); - this.processing = true; - - for await (const fids of gen) { - this.photosDone += fids.filter((f) => f).length; - this.added(this.photos.filter((p) => fids.includes(p.fileid))); - } - + await Promise.all(albums.map(async (album) => { + const name = album.name || album.album_id.toString(); + const gen = dav.addToAlbum(album.user, name, this.photos); + this.processing = true; + + for await (const fids of gen) { + fids.forEach((f) => { + if (f) { + photosDone.add(f); + } + }); + this.photos.forEach((p) => { + if (fids.includes(p.fileid)) { + processed.add(p); + } + }); + } + this.photosDone = photosDone.size; + })); const n = this.photosDone; + this.added(Array.from(processed)); showInfo(this.n('memories', '{n} item added to album', '{n} items added to album', n, { n })); this.close(); }, diff --git a/src/components/modal/AlbumPicker.vue b/src/components/modal/AlbumPicker.vue index bd5a12d3..632a4ad7 100644 --- a/src/components/modal/AlbumPicker.vue +++ b/src/components/modal/AlbumPicker.vue @@ -13,7 +13,7 @@ albumName: album.name, }) " - @click="pickAlbum(album)" + @click.prevent="pickAlbum(album)" > @@ -35,17 +35,35 @@ - - - {{ t('memories', 'Create new album') }} - +
+ + + {{ t('memories', 'Create new album') }} + + +
+ + {{ t('memories', 'Add to albums') }} + + + {{ t('memories', 'And remove from') }} {{ n('memories', '{n} album', '{n} albums', unselectedCount , { + n: unselectedCount, + })}} + +
+
(), + unselectedAlbums: new Set(), + selectedCount: 0, + unselectedCount: 0, }), mounted() { @@ -143,6 +165,9 @@ export default defineComponent({ try { const res = await axios.get(API.ALBUM_LIST(3, this.photoId)); this.albums = res.data; + this.selectedAlbums = new Set(this.albums.filter(album => album.has_file)); + this.unselectedAlbums = new Set(); + this.unselectedCount = 0; } catch (e) { console.error(e); } finally { @@ -151,8 +176,28 @@ export default defineComponent({ }, pickAlbum(album: IAlbum) { - this.$emit('select', album); + if (this.selectedAlbums.has(album)) { + this.selectedAlbums.delete(album); + this.unselectedAlbums.add(album) + } else if (this.unselectedAlbums.has(album)) { + this.selectedAlbums.add(album) + this.unselectedAlbums.delete(album); + } else { + this.selectedAlbums.add(album) + } + + this.unselectedCount = this.albums.reduce((acc, album) => { + if (album.has_file && this.unselectedAlbums.has(album)) { + acc += 1; + } + return acc; + }, 0); this.selectedAlbums.size; + this.selectedCount = this.selectedAlbums.size; }, + + submit() { + this.$emit('select', Array.from(this.selectedAlbums)); + } }, }); @@ -231,5 +276,21 @@ export default defineComponent({ .new-album-button { margin-top: 32px; } + + .actions { + display: flex; + justify-content: space-between; + align-items: flex-start; + } + + .submit-btn-wrapper { + display: flex; + flex-direction: column; + align-items: flex-end; + } + + .remove-notice { + font-size: small; + } }