Revert using display name in shared albums' name

+ Improve rendering of cover and header of shared albums

Signed-off-by: Louis Chemineau <louis@chmn.me>
This commit is contained in:
Louis Chemineau 2023-05-15 17:12:38 +02:00
parent 57b8502d7b
commit 8c71a5323b
15 changed files with 80 additions and 20 deletions

4
.gitignore vendored
View File

@ -22,4 +22,6 @@ vendor
cypress/videos cypress/videos
cypress/snapshots cypress/snapshots
cypress/downloads cypress/downloads
js/*hot-update.*

View File

@ -154,8 +154,7 @@ describe('Manage shared albums', () => {
it('Remove collaborator from an album', () => { it('Remove collaborator from an album', () => {
cy.login(bob) cy.login(bob)
cy.visit('apps/photos/sharedalbums') cy.visit('apps/photos/sharedalbums')
cy.get('ul.collections__list li') cy.get(`[data-test="shared_album_test4 (${alice.userId})"]`).should('have.length', 1)
.should('contain', `shared_album_test4 (${alice.userId})`)
cy.login(alice) cy.login(alice)
cy.visit('/apps/photos') cy.visit('/apps/photos')
@ -185,10 +184,8 @@ describe('Manage shared albums', () => {
it('It should display two shared albums', () => { it('It should display two shared albums', () => {
cy.login(bob) cy.login(bob)
cy.visit('/apps/photos/sharedalbums') cy.visit('/apps/photos/sharedalbums')
cy.get('ul.collections__list li') cy.get(`[data-test="shared_album_test5 (${alice.userId})"]`).should('have.length', 1)
.contains(`shared_album_test5 (${alice.userId})`) cy.get(`[data-test="shared_album_test5 (${charlie.userId})"]`).should('have.length', 1)
cy.get('ul.collections__list li')
.contains(`shared_album_test5 (${charlie.userId})`)
}) })
}) })
}) })

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -30,8 +30,6 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\IMimeTypeLoader; use OCP\Files\IMimeTypeLoader;
use OCP\Security\ISecureRandom; use OCP\Security\ISecureRandom;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCP\IGroup;
use OCP\IUser;
use OCP\IUserManager; use OCP\IUserManager;
use OCP\IGroupManager; use OCP\IGroupManager;
use OCP\IL10N; use OCP\IL10N;
@ -350,7 +348,7 @@ class AlbumMapper {
$rows = $query->executeQuery()->fetchAll(); $rows = $query->executeQuery()->fetchAll();
$collaborators = array_map(function (array $row) { $collaborators = array_map(function (array $row) {
/** @var IUser|IGroup|null */ /** @var string|null */
$displayName = null; $displayName = null;
switch ($row['collaborator_type']) { switch ($row['collaborator_type']) {
@ -541,7 +539,7 @@ class AlbumMapper {
// Suffix album name with the album owner to prevent duplicates. // Suffix album name with the album owner to prevent duplicates.
// Not done for public link as it would like owner's uid. // Not done for public link as it would like owner's uid.
if ($collaboratorType !== self::TYPE_LINK) { if ($collaboratorType !== self::TYPE_LINK) {
$albumName = $row['album_name'].' ('.$this->userManager->get($row['album_user'])->getDisplayName().')'; $albumName = $row['album_name'].' ('.$row['album_user'].')';
} }
$albumsById[$albumId] = new AlbumInfo($albumId, $row['album_user'], $albumName, $row['location'], (int)$row['created'], (int)$row['last_added_photo']); $albumsById[$albumId] = new AlbumInfo($albumId, $row['album_user'], $albumName, $row['location'], (int)$row['created'], (int)$row['last_added_photo']);
} }

View File

@ -25,8 +25,35 @@ namespace OCA\Photos\Sabre\Album;
use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\Conflict; use Sabre\DAV\Exception\Conflict;
use OCA\Photos\Album\AlbumMapper;
use OCA\Photos\Album\AlbumWithFiles;
use OCA\Photos\Service\UserConfigService;
use OCP\Files\IRootFolder;
use OCP\IUserManager;
class SharedAlbumRoot extends AlbumRoot { class SharedAlbumRoot extends AlbumRoot {
private IUserManager $userManager;
public function __construct(
AlbumMapper $albumMapper,
AlbumWithFiles $album,
IRootFolder $rootFolder,
string $userId,
UserConfigService $userConfigService,
IUserManager $userManager
) {
parent::__construct(
$albumMapper,
$album,
$rootFolder,
$userId,
$userConfigService,
$userManager
);
$this->userManager = $userManager;
}
/** /**
* @return void * @return void
*/ */
@ -55,11 +82,16 @@ class SharedAlbumRoot extends AlbumRoot {
} }
/** /**
* Do not reveal collaborators for shared albums. * Return only the owner, and do not reveal other collaborators.
*/ */
public function getCollaborators(): array { public function getCollaborators(): array {
/** @var array{array{'nc:collaborator': array{'id': string, 'label': string, 'type': int}}} */ return [[
return []; 'nc:collaborator' => [
'id' => $this->album->getAlbum()->getUserId(),
'label' => $this->userManager->get($this->album->getAlbum()->getUserId())->getDisplayName(),
'type' => 1,
],
]];
} }
public function setCollaborators($collaborators): array { public function setCollaborators($collaborators): array {

View File

@ -81,7 +81,7 @@ class SharedAlbumsHome extends AlbumsHome {
} }
$this->children = array_map(function (AlbumWithFiles $album) { $this->children = array_map(function (AlbumWithFiles $album) {
return new SharedAlbumRoot($this->albumMapper, $album, $this->rootFolder, $this->userId, $this->userConfigService); return new SharedAlbumRoot($this->albumMapper, $album, $this->rootFolder, $this->userId, $this->userConfigService, $this->userManager);
}, $albums); }, $albums);
} }

View File

@ -34,14 +34,15 @@
:loading="loadingFiles" :loading="loadingFiles"
:params="{ albumName }" :params="{ albumName }"
:path="'/' + albumName" :path="'/' + albumName"
:title="albumName" :title="albumOriginalName"
@refresh="fetchAlbumContent"> @refresh="fetchAlbumContent">
<!-- <UploadPicker :accept="allowedMimes" <!-- <UploadPicker :accept="allowedMimes"
:destination="folder.filename" :destination="folder.filename"
:multiple="true" :multiple="true"
@uploaded="onUpload" /> --> @uploaded="onUpload" /> -->
<div v-if="album.location !== ''" slot="subtitle" class="album__location"> <div v-if="album.location !== ''" slot="subtitle" class="album__location">
<MapMarker />{{ album.location }} <MapMarker />{{ album.location }} {{ t('photos', 'Shared by') }}&nbsp;<NcUserBubble :display-name="album.collaborators[0].label" :user="album.collaborators[0].id" />
</div> </div>
<template v-if="album !== undefined" slot="right"> <template v-if="album !== undefined" slot="right">
<NcButton v-if="album.nbItems !== 0" <NcButton v-if="album.nbItems !== 0"
@ -122,7 +123,7 @@ import Close from 'vue-material-design-icons/Close'
// import Download from 'vue-material-design-icons/Download' // import Download from 'vue-material-design-icons/Download'
// import DownloadMultiple from 'vue-material-design-icons/DownloadMultiple' // import DownloadMultiple from 'vue-material-design-icons/DownloadMultiple'
import { NcActions, NcActionButton, NcButton, NcModal, NcEmptyContent, NcActionSeparator, isMobile } from '@nextcloud/vue' import { NcActions, NcActionButton, NcButton, NcModal, NcEmptyContent, NcActionSeparator, NcUserBubble, isMobile } from '@nextcloud/vue'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import FetchSharedAlbumsMixin from '../mixins/FetchSharedAlbumsMixin.js' import FetchSharedAlbumsMixin from '../mixins/FetchSharedAlbumsMixin.js'
@ -136,6 +137,7 @@ import logger from '../services/logger.js'
import client from '../services/DavClient.js' import client from '../services/DavClient.js'
import DavRequest from '../services/DavRequest.js' import DavRequest from '../services/DavRequest.js'
import { genFileInfo } from '../utils/fileUtils.js' import { genFileInfo } from '../utils/fileUtils.js'
import { translate } from '@nextcloud/l10n'
export default { export default {
name: 'SharedAlbumContent', name: 'SharedAlbumContent',
@ -153,6 +155,7 @@ export default {
NcActionSeparator, NcActionSeparator,
NcButton, NcButton,
NcModal, NcModal,
NcUserBubble,
CollectionContent, CollectionContent,
// ActionDownload, // ActionDownload,
FilesPicker, FilesPicker,
@ -200,6 +203,13 @@ export default {
albumFileIds() { albumFileIds() {
return this.sharedAlbumsFiles[this.albumName] || [] return this.sharedAlbumsFiles[this.albumName] || []
}, },
/**
* @return {string} The album name without the userId between parentheses.
*/
albumOriginalName() {
return this.albumName.replace(new RegExp(`\\(${this.album.collaborators[0].id}\\)$`), '')
},
}, },
watch: { watch: {
@ -285,6 +295,8 @@ export default {
await this.deleteSharedAlbum({ albumName: this.albumName }) await this.deleteSharedAlbum({ albumName: this.albumName })
this.$router.push('/sharedalbums') this.$router.push('/sharedalbums')
}, },
t: translate,
}, },
} }
</script> </script>

View File

@ -35,13 +35,16 @@
slot-scope="{collection}" slot-scope="{collection}"
:link="`/sharedalbums/${collection.basename}`" :link="`/sharedalbums/${collection.basename}`"
:alt-img="t('photos', 'Cover photo for shared album {albumName}.', { albumName: collection.basename })" :alt-img="t('photos', 'Cover photo for shared album {albumName}.', { albumName: collection.basename })"
:data-test="collection.basename"
:cover-url="collection.lastPhoto | coverUrl"> :cover-url="collection.lastPhoto | coverUrl">
<h2 class="album__name"> <h2 class="album__name">
{{ collection.basename }} {{ collection | albumOriginalName }}
</h2> </h2>
<div slot="subtitle" class="album__details"> <div slot="subtitle" class="album__details">
{{ collection.date }} {{ n('photos', '%n item', '%n photos and videos', collection.nbItems,) }} {{ collection.date }} {{ n('photos', '%n item', '%n photos and videos', collection.nbItems,) }}
<br>
{{ t('photos', 'Shared by') }}&nbsp;<NcUserBubble :display-name="collection.collaborators[0].label" :user="collection.collaborators[0].id" />
</div> </div>
</CollectionCover> </CollectionCover>
@ -55,12 +58,13 @@
import FolderMultipleImage from 'vue-material-design-icons/FolderMultipleImage' import FolderMultipleImage from 'vue-material-design-icons/FolderMultipleImage'
import { generateUrl } from '@nextcloud/router' import { generateUrl } from '@nextcloud/router'
import { NcEmptyContent } from '@nextcloud/vue' import { NcEmptyContent, NcUserBubble } from '@nextcloud/vue'
import FetchSharedAlbumsMixin from '../mixins/FetchSharedAlbumsMixin.js' import FetchSharedAlbumsMixin from '../mixins/FetchSharedAlbumsMixin.js'
import CollectionsList from '../components/Collection/CollectionsList.vue' import CollectionsList from '../components/Collection/CollectionsList.vue'
import CollectionCover from '../components/Collection/CollectionCover.vue' import CollectionCover from '../components/Collection/CollectionCover.vue'
import HeaderNavigation from '../components/HeaderNavigation.vue' import HeaderNavigation from '../components/HeaderNavigation.vue'
import { translate, translatePlural } from '@nextcloud/l10n'
export default { export default {
name: 'SharedAlbums', name: 'SharedAlbums',
@ -70,11 +74,13 @@ export default {
CollectionsList, CollectionsList,
CollectionCover, CollectionCover,
HeaderNavigation, HeaderNavigation,
NcUserBubble,
}, },
filters: { filters: {
/** /**
* @param {string} lastPhoto The album's last photos. * @param {string} lastPhoto The album's last photos.
* @return {string}
*/ */
coverUrl(lastPhoto) { coverUrl(lastPhoto) {
if (lastPhoto === -1) { if (lastPhoto === -1) {
@ -83,11 +89,24 @@ export default {
return generateUrl(`/apps/photos/api/v1/preview/${lastPhoto}?x=${512}&y=${512}`) return generateUrl(`/apps/photos/api/v1/preview/${lastPhoto}?x=${512}&y=${512}`)
}, },
/**
* @param {import('../services/Albums.js').Album} album The album's full name, including the userid.
* @return {string} The album name without the userId between parentheses.
*/
albumOriginalName(album) {
return album.basename.replace(new RegExp(`\\(${album.collaborators[0].id}\\)$`), '')
},
}, },
mixins: [ mixins: [
FetchSharedAlbumsMixin, FetchSharedAlbumsMixin,
], ],
methods: {
t: translate,
n: translatePlural,
},
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>