album: refactor add modal

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/767/head
Varun Patil 2023-08-02 12:28:44 -07:00
parent d32793e9c0
commit 254329e1c2
4 changed files with 58 additions and 45 deletions

View File

@ -34,7 +34,7 @@
<!-- Selection Modals --> <!-- Selection Modals -->
<FaceMoveModal ref="faceMoveModal" @moved="deletePhotos" :updateLoading="updateLoading" /> <FaceMoveModal ref="faceMoveModal" @moved="deletePhotos" :updateLoading="updateLoading" />
<AddToAlbumModal ref="addToAlbumModal" @added="clearSelection" /> <AddToAlbumModal ref="addToAlbumModal" @change="clearSelection" />
<MoveToFolderModal ref="moveToFolderModal" @moved="refresh" /> <MoveToFolderModal ref="moveToFolderModal" @moved="refresh" />
</div> </div>
</template> </template>

View File

@ -5,9 +5,9 @@
</template> </template>
<div class="outer"> <div class="outer">
<AlbumPicker @select="updateAlbums" :photos="photos" /> <AlbumPicker @select="update" :photos="photos" :disabled="!!opsTotal" />
<div v-if="processing"> <div class="progress-bar" v-if="opsTotal">
<NcProgressBar :value="progress" :error="true" /> <NcProgressBar :value="progress" :error="true" />
</div> </div>
</div> </div>
@ -37,60 +37,54 @@ export default defineComponent({
data: () => ({ data: () => ({
show: false, show: false,
photos: [] as IPhoto[], photos: [] as IPhoto[],
progress: 0, opsDone: 0,
processing: false, opsTotal: 0,
processed: new Set<IPhoto>(),
photosDone: 0,
totalOperations: 0,
}), }),
computed: {
progress(): number {
return Math.min(this.opsTotal ? Math.round((this.opsDone * 100) / this.opsTotal) : 100, 100);
},
},
methods: { methods: {
open(photos: IPhoto[]) { open(photos: IPhoto[]) {
this.progress = 0;
this.processing = false;
this.show = true;
this.photos = photos; this.photos = photos;
}, this.show = true;
this.opsTotal = 0;
added(photos: IPhoto[]) {
this.$emit('added', photos);
}, },
close() { close() {
this.photos = [];
this.processing = false;
this.show = false; this.show = false;
this.photos = [];
this.opsTotal = 0;
this.$emit('close'); this.$emit('close');
}, },
async processAlbum(album: IAlbum, action: 'add' | 'remove') { async update(selection: IAlbum[], deselection: IAlbum[]) {
const name = album.name || album.album_id.toString(); if (this.opsTotal) return;
const gen = action === 'add'
? dav.addToAlbum(album.user, name, this.photos) // Total number of DAV calls (ugh DAV)
: dav.removeFromAlbum(album.user, name, this.photos); this.opsTotal = this.photos.length * (selection.length + deselection.length);
for await (const fids of gen) { // Add the photos to the selected albums
this.photosDone += fids.length; for (const album of selection) {
this.photos.forEach((p) => { for await (const fids of dav.addToAlbum(album.user, album.name, this.photos)) {
if (fids.includes(p.fileid)) { this.opsDone += fids.filter((f) => f).length;
this.processed.add(p); }
}
});
} }
this.progress = Math.round((this.photosDone * 100) / this.totalOperations);
},
async updateAlbums(albumsToAddTo: IAlbum[], albumsToRemoveFrom: IAlbum[] = []) { // Remove the photos from the deselected albums
if (this.processing) return; for (const album of deselection) {
this.processing = true; for await (const fids of dav.removeFromAlbum(album.user, album.name, this.photos)) {
this.processed = new Set<IPhoto>(); this.opsDone += fids.filter((f) => f).length;
this.totalOperations = this.photos.length * (albumsToAddTo.length + albumsToRemoveFrom.length); }
}
await Promise.all(albumsToAddTo.map((album) => this.processAlbum(album, 'add'))); const n = this.photos.length;
await Promise.all(albumsToRemoveFrom.map((album) => this.processAlbum(album, 'remove'))); showInfo(this.n('memories', '{n} photo updated', '{n} photos updated', n, { n }));
const n = this.processed.size;
this.added(Array.from(this.processed)); this.$emit('change');
showInfo(this.n('memories', '{n} processed', '{n} processed', n, { n }));
this.close(); this.close();
}, },
}, },
@ -101,4 +95,8 @@ export default defineComponent({
.outer { .outer {
margin-top: 15px; margin-top: 15px;
} }
.progress-bar {
margin-top: 10px;
}
</style> </style>

View File

@ -159,7 +159,7 @@ type Collaborator = {
}; };
export default defineComponent({ export default defineComponent({
name: 'AddToAlbumModal', name: 'AlbumCollaborators',
components: { components: {
Magnify, Magnify,
Close, Close,

View File

@ -43,7 +43,8 @@
<div class="actions"> <div class="actions">
<NcButton <NcButton
:aria-label="t('memories', 'Create a new album.')" :aria-label="t('memories', 'Create new album.')"
:disabled="disabled"
class="new-album-button" class="new-album-button"
type="tertiary" type="tertiary"
@click="showAlbumCreationForm = true" @click="showAlbumCreationForm = true"
@ -55,7 +56,13 @@
</NcButton> </NcButton>
<div class="submit-btn-wrapper"> <div class="submit-btn-wrapper">
<NcButton :aria-label="t('memories', 'Save')" class="new-album-button" type="primary" @click="submit"> <NcButton
class="new-album-button"
type="primary"
:aria-label="t('memories', 'Save changes')"
:disabled="disabled"
@click="submit"
>
{{ t('memories', 'Save changes') }} {{ t('memories', 'Save changes') }}
</NcButton> </NcButton>
<span class="remove-notice" v-if="deselection.size > 0"> <span class="remove-notice" v-if="deselection.size > 0">
@ -107,6 +114,12 @@ export default defineComponent({
type: Array as PropType<IPhoto[]>, type: Array as PropType<IPhoto[]>,
required: true, required: true,
}, },
/** Disable controls */
disabled: {
type: Boolean,
default: false,
},
}, },
components: { components: {
AlbumForm, AlbumForm,
@ -180,6 +193,8 @@ export default defineComponent({
}, },
toggleAlbumSelection(album: IAlbum) { toggleAlbumSelection(album: IAlbum) {
if (this.disabled) return;
if (this.selection.has(album)) { if (this.selection.has(album)) {
this.selection.delete(album); this.selection.delete(album);