Fixes indicator styling, adds info whether an album contains selected file

Signed-off-by: Alexander Saltykov <temp.kroogi@gmail.com>
pull/752/head
Alexander Saltykov 2023-07-24 22:35:25 +03:00
parent 3663a31df0
commit 2457eb70aa
6 changed files with 66 additions and 34 deletions

View File

@ -95,11 +95,12 @@ class AlbumsBackend extends Backend
// Run actual query // Run actual query
$list = []; $list = [];
$t = (int) $request->getParam('t', 0); $t = (int) $request->getParam('t', 0);
$fileid = (int) $request->getParam('fid', -1);
if ($t & 1) { // personal if ($t & 1) { // personal
$list = array_merge($list, $this->albumsQuery->getList(Util::getUID())); $list = array_merge($list, $this->albumsQuery->getList(Util::getUID(), $fileid));
} }
if ($t & 2) { // shared if ($t & 2) { // shared
$list = array_merge($list, $this->albumsQuery->getList(Util::getUID(), true)); $list = array_merge($list, $this->albumsQuery->getList(Util::getUID(), $fileid, true));
} }
// Remove elements with duplicate album_id // Remove elements with duplicate album_id

View File

@ -17,11 +17,16 @@ class AlbumsQuery
} }
/** Get list of albums */ /** Get list of albums */
public function getList(string $uid, bool $shared = false) public function getList(string $uid, int $fileId, bool $shared = false)
{ {
$query = $this->connection->getQueryBuilder(); $query = $this->connection->getQueryBuilder();
$allPhotosQuery = $this->connection->getQueryBuilder();
// SELECT everything from albums // SELECT everything from albums
$allPhotosQuery->select('album_id')->from('photos_albums_files');
$allPhotosQuery->where(
$allPhotosQuery->expr()->eq('file_id', $allPhotosQuery->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))
);
$count = $query->func()->count($query->createFunction('DISTINCT m.fileid'), 'count'); $count = $query->func()->count($query->createFunction('DISTINCT m.fileid'), 'count');
$query->select( $query->select(
'pa.album_id', 'pa.album_id',
@ -64,13 +69,21 @@ class AlbumsQuery
// FETCH all albums // FETCH all albums
$albums = $query->executeQuery()->fetchAll(); $albums = $query->executeQuery()->fetchAll();
$allPhotos = $allPhotosQuery->executeQuery()->fetchAll();
$albumIds = array();
foreach ($allPhotos as &$album) {
$albumIds[$album['album_id']] = true;
}
// Post process // Post process
foreach ($albums as &$row) { foreach ($albums as &$row) {
$albumId = (int) $row['album_id'];
$row['cluster_id'] = $row['user'].'/'.$row['name']; $row['cluster_id'] = $row['user'].'/'.$row['name'];
$row['album_id'] = (int) $row['album_id']; $row['album_id'] = $albumId;
$row['created'] = (int) $row['created']; $row['created'] = (int) $row['created'];
$row['last_added_photo'] = (int) $row['last_added_photo']; $row['last_added_photo'] = (int) $row['last_added_photo'];
$row['has_file'] = !!$albumIds[$albumId];
} }
return $albums; return $albums;

View File

@ -0,0 +1,5 @@
<?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>

After

Width:  |  Height:  |  Size: 350 B

View File

@ -3,20 +3,11 @@
<XLoadingIcon v-if="loadingAlbums" class="loading-icon" /> <XLoadingIcon v-if="loadingAlbums" class="loading-icon" />
<ul class="albums-container"> <ul class="albums-container">
<NcListItem <NcListItem v-for="album in albums" class="album" :key="album.album_id" :title="album.name" :aria-label="t('memories', 'Add selection to album {albumName}', {
v-for="album in albums" albumName: album.name,
class="album" })
:key="album.album_id" " @click="pickAlbum(album)">
:title="album.name"
:aria-label="
t('memories', 'Add selection to album {albumName}', {
albumName: album.name,
})
"
@click="pickAlbum(album)"
>
<template #icon> <template #icon>
<div v-if="photoId === album.last_added_photo">OK</div>
<XImg v-if="album.last_added_photo !== -1" class="album__image" :src="toCoverUrl(album.last_added_photo)" /> <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"> <div v-else class="album__image album__image--placeholder">
<ImageMultiple :size="32" /> <ImageMultiple :size="32" />
@ -26,15 +17,18 @@
<template #subtitle> <template #subtitle>
{{ getSubtitle(album) }} {{ getSubtitle(album) }}
</template> </template>
<template #extra>
<div v-if="album.has_file" class="check-circle-icon">
<XImg :src="checkmarkIcon" />
</div>
</template>
</NcListItem> </NcListItem>
</ul> </ul>
<NcButton <NcButton :aria-label="t('memories', 'Create a new album.')" class="new-album-button" type="tertiary"
:aria-label="t('memories', 'Create a new album.')" @click="showAlbumCreationForm = true">
class="new-album-button"
type="tertiary"
@click="showAlbumCreationForm = true"
>
<template #icon> <template #icon>
<Plus /> <Plus />
</template> </template>
@ -42,13 +36,8 @@
</NcButton> </NcButton>
</div> </div>
<AlbumForm <AlbumForm v-else :display-back-button="true" :title="t('memories', 'New album')" @back="showAlbumCreationForm = false"
v-else @done="albumCreatedHandler" />
:display-back-button="true"
:title="t('memories', 'New album')"
@back="showAlbumCreationForm = false"
@done="albumCreatedHandler"
/>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -59,6 +48,7 @@ import { getCurrentUser } from '@nextcloud/auth';
import AlbumForm from './AlbumForm.vue'; import AlbumForm from './AlbumForm.vue';
import Plus from 'vue-material-design-icons/Plus.vue'; import Plus from 'vue-material-design-icons/Plus.vue';
import ImageMultiple from 'vue-material-design-icons/ImageMultiple.vue'; import ImageMultiple from 'vue-material-design-icons/ImageMultiple.vue';
import checkmarkIcon from '../../assets/checkmark.svg';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
@ -92,14 +82,15 @@ export default defineComponent({
albums: [] as IAlbum[], albums: [] as IAlbum[],
loadingAlbums: true, loadingAlbums: true,
photoId: -1, photoId: -1,
checkmarkIcon,
}), }),
mounted() { mounted() {
this.loadAlbums();
if (this.photos.length === 1) { if (this.photos.length === 1) {
// this only makes sense when we try to add single photo to albums // this only makes sense when we try to add single photo to albums
this.photoId = this.photos[0].fileid; this.photoId = this.photos[0].fileid;
} }
this.loadAlbums();
}, },
methods: { methods: {
@ -133,7 +124,7 @@ export default defineComponent({
async loadAlbums() { async loadAlbums() {
try { try {
const res = await axios.get<IAlbum[]>(API.ALBUM_LIST()); const res = await axios.get<IAlbum[]>(API.ALBUM_LIST(3, this.photoId));
this.albums = res.data; this.albums = res.data;
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -170,6 +161,11 @@ export default defineComponent({
.album { .album {
:deep .list-item { :deep .list-item {
box-sizing: border-box; box-sizing: border-box;
display: flex;
}
:deep .list-item-content__wrapper {
flex-grow: 1;
} }
:deep .line-one__title { :deep .line-one__title {
@ -198,6 +194,21 @@ export default defineComponent({
} }
} }
} }
.check-circle-icon {
border-radius: 50%;
background-color: rgba(0, 255, 0, 0.1882352941);
height: 34px;
width: 34px;
display: flex;
align-items: center;
justify-content: center;
& img {
width: 50%;
height: 50%;
}
}
} }
.new-album-button { .new-album-button {

View File

@ -84,8 +84,8 @@ export class API {
return tok(gen(`${BASE}/folders/sub`)); return tok(gen(`${BASE}/folders/sub`));
} }
static ALBUM_LIST(t: 1 | 2 | 3 = 3) { static ALBUM_LIST(t: 1 | 2 | 3 = 3, photoId: number = -1) {
return gen(`${BASE}/clusters/albums?t=${t}`); return gen(`${BASE}/clusters/albums?t=${t}&fid=${photoId}`);
} }
static ALBUM_DOWNLOAD(user: string, name: string) { static ALBUM_DOWNLOAD(user: string, name: string) {

View File

@ -140,6 +140,8 @@ export interface IAlbum extends ICluster {
location: string; location: string;
/** File ID of last added photo */ /** File ID of last added photo */
last_added_photo: number; last_added_photo: number;
/** Whether an album contains the file */
has_file: boolean;
} }
export interface IFace extends ICluster { export interface IFace extends ICluster {