album: refactor picker

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/767/head
Varun Patil 2023-08-02 12:01:12 -07:00
parent 5890daba1a
commit d32793e9c0
2 changed files with 57 additions and 78 deletions

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" fill="none"/>
<path d="M5 13.3636L8.03559 16.3204C8.42388 16.6986 9.04279 16.6986 9.43108 16.3204L19 7" stroke="#000000" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 350 B

View File

@ -13,38 +13,31 @@
albumName: album.name,
})
"
@click.prevent="() => {}"
@click.prevent="toggleAlbumSelection(album)"
>
<template #icon>
<XImg v-if="album.last_added_photo !== -1" class="album__image" :src="toCoverUrl(album.last_added_photo)" />
<div v-else class="album__image album__image--placeholder">
<ImageMultiple :size="32" />
<ImageMultipleIcon :size="32" />
</div>
</template>
<template #subtitle>
<div @click.prevent="pickAlbum(album)">
<div>
{{ getSubtitle(album) }}
</div>
</template>
<template #extra>
<div
v-if="!selectedAlbums.has(album)"
class="check-circle-icon check-circle-icon--inactive"
@click.prevent="toggleAlbumSelection(album)"
>
<XImg :src="checkmarkIcon" />
</div>
<div
v-if="selectedAlbums.has(album)"
class="check-circle-icon"
@click.prevent="toggleAlbumSelection(album)"
:class="{
'check-circle-icon--active': selection.has(album),
}"
>
<XImg :src="checkmarkIcon" />
<CheckIcon :size="20" />
</div>
</template>
</NcListItem>
</ul>
@ -56,24 +49,21 @@
@click="showAlbumCreationForm = true"
>
<template #icon>
<Plus />
<PlusIcon />
</template>
{{ t('memories', 'Create new album') }}
</NcButton>
<div class="submit-btn-wrapper">
<NcButton
:aria-label="t('memories', `Add to ${selectedCount} albums.`)"
class="new-album-button"
type="primary"
@click="submit"
>
{{ t('memories', 'Add to albums') }}
<NcButton :aria-label="t('memories', 'Save')" class="new-album-button" type="primary" @click="submit">
{{ t('memories', 'Save changes') }}
</NcButton>
<span class="remove-notice" v-if="unselectedCount > 0">
{{ t('memories', 'And remove from') }} {{ n('memories', '{n} album', '{n} albums', unselectedCount , {
n: unselectedCount,
})}}
<span class="remove-notice" v-if="deselection.size > 0">
{{
n('memories', 'Removed from {n} album', 'Removed from {n} albums', deselection.size, {
n: this.deselection.size,
})
}}
</span>
</div>
</div>
@ -94,9 +84,6 @@ import { defineComponent } from 'vue';
import { getCurrentUser } from '@nextcloud/auth';
import AlbumForm from './AlbumForm.vue';
import Plus from 'vue-material-design-icons/Plus.vue';
import ImageMultiple from 'vue-material-design-icons/ImageMultiple.vue';
import checkmarkIcon from '../../assets/checkmark.svg';
import axios from '@nextcloud/axios';
@ -108,6 +95,10 @@ import { IAlbum, IPhoto } from '../../types';
import { API } from '../../services/API';
import { PropType } from 'vue';
import PlusIcon from 'vue-material-design-icons/Plus.vue';
import ImageMultipleIcon from 'vue-material-design-icons/ImageMultiple.vue';
import CheckIcon from 'vue-material-design-icons/Check.vue';
export default defineComponent({
name: 'AlbumPicker',
props: {
@ -119,29 +110,26 @@ export default defineComponent({
},
components: {
AlbumForm,
Plus,
ImageMultiple,
NcButton,
NcListItem,
PlusIcon,
ImageMultipleIcon,
CheckIcon,
},
data: () => ({
showAlbumCreationForm: false,
albums: [] as IAlbum[],
loadingAlbums: true,
photoId: -1,
checkmarkIcon,
selectedAlbums: new Set<IAlbum>(),
unselectedAlbums: new Set<IAlbum>(),
selectedCount: 0,
unselectedCount: 0,
/** List of all albums */
albums: [] as IAlbum[],
/** All selected albums */
selection: new Set<IAlbum>(),
/** Deselected albums that were previously selected */
deselection: new Set<IAlbum>(),
}),
mounted() {
if (this.photos.length === 1) {
// this only makes sense when we try to add single photo to albums
this.photoId = this.photos[0].fileid;
}
this.loadAlbums();
},
@ -176,11 +164,14 @@ export default defineComponent({
async loadAlbums() {
try {
const res = await axios.get<IAlbum[]>(API.ALBUM_LIST(3, this.photoId));
// this only makes sense when we try to add single photo to albums
const photoId = this.photos.length === 1 ? this.photos[0].fileid : -1;
// get albums, possibly for one photo
const res = await axios.get<IAlbum[]>(API.ALBUM_LIST(3, photoId));
this.albums = res.data;
this.selectedAlbums = new Set(this.albums.filter(album => album.has_file));
this.unselectedAlbums = new Set();
this.unselectedCount = 0;
this.selection = new Set(this.albums.filter((album) => album.has_file));
this.deselection = new Set();
} catch (e) {
console.error(e);
} finally {
@ -189,32 +180,24 @@ export default defineComponent({
},
toggleAlbumSelection(album: IAlbum) {
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;
if (this.selection.has(album)) {
this.selection.delete(album);
// deselection only if originally selected
if (album.has_file) {
this.deselection.add(album);
}
return acc;
}, 0); this.selectedAlbums.size;
this.selectedCount = this.selectedAlbums.size;
} else {
this.selection.add(album);
this.deselection.delete(album);
}
this.$forceUpdate(); // sets do not trigger reactivity
},
pickAlbum(album: IAlbum) {
this.$emit('select', [album], []);
},
submit() {
this.$emit('select', Array.from(this.selectedAlbums), Array.from(this.unselectedAlbums));
}
this.$emit('select', Array.from(this.selection), Array.from(this.deselection));
},
},
});
</script>
@ -276,17 +259,18 @@ export default defineComponent({
.check-circle-icon {
border-radius: 50%;
border: 1px solid rgba(0, 255, 0, 0.1882352941);
background-color: rgba(0, 255, 0, 0.1882352941);
border: 1px solid rgba($color: black, $alpha: 0.1);
background-color: transparent;
height: 34px;
width: 34px;
display: flex;
align-items: center;
justify-content: center;
&--inactive {
border: 1px solid rgba($color: black, $alpha: 0.1);
background-color: transparent;
&--active {
border: 1px solid var(--color-primary);
background-color: var(--color-primary-default);
color: var(--color-primary-text);
}
& img {