diff options
author | Louis Chemineau <louis@chmn.me> | 2022-09-26 19:17:35 +0300 |
---|---|---|
committer | Louis Chemineau <louis@chmn.me> | 2022-10-20 12:54:09 +0300 |
commit | 4f751b59fa41c14979e95039ba4c6bc386295834 (patch) | |
tree | a0bbc819a9500fe17e2e254139454ee084b5a0e6 | |
parent | 57b02f1c105cbec0ee64472a80b32dc7253f1302 (diff) |
Cleaning before review
Signed-off-by: Louis Chemineau <louis@chmn.me>
-rw-r--r-- | appinfo/routes.php | 1 | ||||
-rw-r--r-- | lib/Album/AlbumMapper.php | 1 | ||||
-rw-r--r-- | lib/Sabre/PhotosHome.php | 23 | ||||
-rw-r--r-- | package-lock.json | 17 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/components/Albums/CollaboratorsSelectionForm.vue | 27 | ||||
-rw-r--r-- | src/store/publicAlbums.js | 213 | ||||
-rw-r--r-- | src/views/PublicAlbumContent.vue | 14 |
8 files changed, 46 insertions, 251 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 2389fc2d..5ae06249 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -83,7 +83,6 @@ return [ 'path' => '.*', ], ], - [ 'name' => 'public#get', 'url' => '/display/{token}', 'verb' => 'GET' ], ['name' => 'page#index', 'url' => '/tags/{path}', 'verb' => 'GET', 'postfix' => 'tags', 'requirements' => [ 'path' => '.*', diff --git a/lib/Album/AlbumMapper.php b/lib/Album/AlbumMapper.php index d5a53cfb..baf1a728 100644 --- a/lib/Album/AlbumMapper.php +++ b/lib/Album/AlbumMapper.php @@ -313,7 +313,6 @@ class AlbumMapper { break; case self::TYPE_LINK: $displayName = $this->l->t('Public link'); - ; break; default: throw new \Exception('Invalid collaborator type: ' . $row['collaborator_type']); diff --git a/lib/Sabre/PhotosHome.php b/lib/Sabre/PhotosHome.php index ba4d266e..00ee2f0c 100644 --- a/lib/Sabre/PhotosHome.php +++ b/lib/Sabre/PhotosHome.php @@ -90,26 +90,31 @@ class PhotosHome implements ICollection { } public function getChild($name) { - if ($name === 'albums') { - return new AlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService); - } elseif ($name === 'sharedalbums') { - return new SharedAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->groupManager, $this->userConfigService); - } elseif ($name === 'public') { - return new PublicAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService); + switch ($name) { + case 'albums': + return new AlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService); + case 'sharedalbums': + return new SharedAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->groupManager, $this->userConfigService); + case 'public': + return new PublicAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService); } throw new NotFound(); } /** - * @return (AlbumsHome|SharedAlbumsHome|PublicAlbumHome)[] + * @return (AlbumsHome)[] */ public function getChildren(): array { - return [new AlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService)]; + return [ + new AlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService), + new SharedAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->groupManager, $this->userConfigService), + new PublicAlbumsHome($this->principalInfo, $this->albumMapper, $this->user, $this->rootFolder, $this->userConfigService), + ]; } public function childExists($name): bool { - return $name === 'albums' || $name === 'sharedalbums'; + return $name === 'albums' || $name === 'sharedalbums' || $name === 'public'; } public function getLastModified(): int { diff --git a/package-lock.json b/package-lock.json index 44f6e56c..85860d2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@nextcloud/moment": "^1.2.1", "@nextcloud/paths": "^2.1.0", "@nextcloud/router": "^2.0.0", + "@nextcloud/sharing": "^0.1.0", "@nextcloud/upload": "^1.0.0-beta.8", "@nextcloud/vue": "^7.0.0-beta.4", "camelcase": "^7.0.0", @@ -3395,6 +3396,14 @@ "core-js": "^3.6.4" } }, + "node_modules/@nextcloud/sharing": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/sharing/-/sharing-0.1.0.tgz", + "integrity": "sha512-Cv4uc1aFrA18w0dltq7a5om/EbJSXf36rtO0LP3vi42E6l8ZDVCZwHLKrsZZa/TXNLeYErs1g/6tmWx5xiSSow==", + "dependencies": { + "core-js": "^3.6.4" + } + }, "node_modules/@nextcloud/stylelint-config": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@nextcloud/stylelint-config/-/stylelint-config-2.2.0.tgz", @@ -22605,6 +22614,14 @@ "core-js": "^3.6.4" } }, + "@nextcloud/sharing": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@nextcloud/sharing/-/sharing-0.1.0.tgz", + "integrity": "sha512-Cv4uc1aFrA18w0dltq7a5om/EbJSXf36rtO0LP3vi42E6l8ZDVCZwHLKrsZZa/TXNLeYErs1g/6tmWx5xiSSow==", + "requires": { + "core-js": "^3.6.4" + } + }, "@nextcloud/stylelint-config": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@nextcloud/stylelint-config/-/stylelint-config-2.2.0.tgz", diff --git a/package.json b/package.json index 151882eb..371cbafd 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@nextcloud/moment": "^1.2.1", "@nextcloud/paths": "^2.1.0", "@nextcloud/router": "^2.0.0", + "@nextcloud/sharing": "^0.1.0", "@nextcloud/upload": "^1.0.0-beta.8", "@nextcloud/vue": "^7.0.0-beta.4", "camelcase": "^7.0.0", diff --git a/src/components/Albums/CollaboratorsSelectionForm.vue b/src/components/Albums/CollaboratorsSelectionForm.vue index b7658835..afc9d633 100644 --- a/src/components/Albums/CollaboratorsSelectionForm.vue +++ b/src/components/Albums/CollaboratorsSelectionForm.vue @@ -140,6 +140,7 @@ import { showError } from '@nextcloud/dialogs' import { getCurrentUser } from '@nextcloud/auth' import { generateOcsUrl, generateUrl } from '@nextcloud/router' import { NcButton, NcListItemIcon, NcLoadingIcon, NcPopover, NcTextField, NcEmptyContent } from '@nextcloud/vue' +import { Type } from '@nextcloud/sharing' import logger from '../../services/logger.js' import AbortControllerMixin from '../../mixins/AbortControllerMixin.js' @@ -149,7 +150,7 @@ import { fetchAlbum } from '../../services/Albums.js' * @typedef {object} Collaborator * @property {string} id - The id of the collaborator. * @property {string} label - The label of the collaborator for display. - * @property {0|1|3} type - The type of the collaborator. + * @property {Type.SHARE_TYPE_USER|Type.SHARE_TYPE_GROUP|Type.SHARE_TYPE_LINK} type - The type of the collaborator. */ export default { @@ -226,7 +227,7 @@ export default { */ listableSelectedCollaboratorsKeys() { return this.selectedCollaboratorsKeys - .filter(collaboratorKey => this.availableCollaborators[collaboratorKey].type !== OC.Share.SHARE_TYPE_LINK) + .filter(collaboratorKey => this.availableCollaborators[collaboratorKey].type !== Type.SHARE_TYPE_LINK) }, /** @@ -241,12 +242,12 @@ export default { * @return {boolean} */ isPublicLinkSelected() { - return this.selectedCollaboratorsKeys.includes(OC.Share.SHARE_TYPE_LINK.toString()) + return this.selectedCollaboratorsKeys.includes(`${Type.SHARE_TYPE_LINK}`) }, /** @return {Collaborator} */ publicLink() { - return this.availableCollaborators[OC.Share.SHARE_TYPE_LINK] + return this.availableCollaborators[Type.SHARE_TYPE_LINK] }, }, @@ -279,8 +280,8 @@ export default { search: this.searchText, itemType: 'share-recipients', shareTypes: [ - OC.Share.SHARE_TYPE_USER, - OC.Share.SHARE_TYPE_GROUP, + Type.SHARE_TYPE_USER, + Type.SHARE_TYPE_GROUP, ], }, }) @@ -289,9 +290,9 @@ export default { .map(collaborator => { switch (collaborator.source) { case 'users': - return { id: collaborator.id, label: collaborator.label, type: OC.Share.SHARE_TYPE_USER } + return { id: collaborator.id, label: collaborator.label, type: Type.SHARE_TYPE_USER } case 'groups': - return { id: collaborator.id, label: collaborator.label, type: OC.Share.SHARE_TYPE_GROUP } + return { id: collaborator.id, label: collaborator.label, type: Type.SHARE_TYPE_GROUP } default: throw new Error(`Invalid collaborator source ${collaborator.source}`) } @@ -322,7 +323,7 @@ export default { 3: { id: '', label: t('photos', 'Public link'), - type: OC.Share.SHARE_TYPE_LINK, + type: Type.SHARE_TYPE_LINK, }, ...this.availableCollaborators, ...initialCollaborators, @@ -334,11 +335,11 @@ export default { * @param {Collaborator} collaborator - A collaborator */ indexCollaborators(collaborators, collaborator) { - return { ...collaborators, [`${collaborator.type}${collaborator.type === OC.Share.SHARE_TYPE_LINK ? '' : ':'}${collaborator.type === OC.Share.SHARE_TYPE_LINK ? '' : collaborator.id}`]: collaborator } + return { ...collaborators, [`${collaborator.type}${collaborator.type === Type.SHARE_TYPE_LINK ? '' : ':'}${collaborator.type === Type.SHARE_TYPE_LINK ? '' : collaborator.id}`]: collaborator } }, async createPublicLinkForAlbum() { - this.selectEntity(OC.Share.SHARE_TYPE_LINK.toString()) + this.selectEntity(`${Type.SHARE_TYPE_LINK}`) await this.updateAlbumCollaborators() try { this.loadingAlbum = true @@ -365,11 +366,11 @@ export default { }, async deletePublicLink() { - this.unselectEntity(OC.Share.SHARE_TYPE_LINK.toString()) + this.unselectEntity(`${Type.SHARE_TYPE_LINK}`) this.availableCollaborators[3] = { id: '', label: t('photos', 'Public link'), - type: OC.Share.SHARE_TYPE_LINK, + type: Type.SHARE_TYPE_LINK, } this.publicLinkCopied = false await this.updateAlbumCollaborators() diff --git a/src/store/publicAlbums.js b/src/store/publicAlbums.js deleted file mode 100644 index 03a84757..00000000 --- a/src/store/publicAlbums.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @copyright Copyright (c) 2022 Louis Chemineau <louis@chmn.me> - * - * @author Louis Chemineau <louis@chmn.me> - * - * @license AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -import { showError } from '@nextcloud/dialogs' - -import client from '../services/DavClient.js' -import logger from '../services/logger.js' -import Semaphore from '../utils/semaphoreWithPriority.js' - -/** - * @typedef {object} Album - * @property {string} basename - The name of the album. - * @property {number} lastmod - The creation date of the album. - * @property {string} size - The number of items in the album. - */ - -const state = { - sharedAlbums: {}, - sharedAlbumsFiles: {}, -} - -const mutations = { - /** - * Add albums to the album collection. - * - * @param {object} state vuex state - * @param {object} data destructuring object - * @param {Array} data.albums list of albums - */ - addSharedAlbums(state, { albums }) { - state.sharedAlbums = { - ...state.sharedAlbums, - ...albums.reduce((albums, album) => ({ ...albums, [album.basename]: album }), {}), - } - }, - - /** - * Remove albums from the album collection. - * - * @param {object} state vuex state - * @param {object} data destructuring object - * @param {Array} data.albumNames list of albums ids - */ - removeSharedAlbums(state, { albumNames }) { - albumNames.forEach(albumName => delete state.sharedAlbums[albumName]) - albumNames.forEach(albumName => delete state.sharedAlbumsFiles[albumName]) - }, - - /** - * Add files to an album. - * - * @param {object} state vuex state - * @param {object} data destructuring object - * @param {string} data.albumName the album id - * @param {string[]} data.fileIdsToAdd list of files - */ - addFilesToSharedAlbum(state, { albumName, fileIdsToAdd }) { - const albumFiles = state.sharedAlbumsFiles[albumName] || [] - state.sharedAlbumsFiles = { - ...state.sharedAlbumsFiles, - [albumName]: [ - ...albumFiles, - ...fileIdsToAdd.filter(fileId => !albumFiles.includes(fileId)), // Filter to prevent duplicate fileId. - ], - } - state.sharedAlbums[albumName].nbItems += fileIdsToAdd.length - }, - - /** - * Remove files to an album. - * - * @param {object} state vuex state - * @param {object} data destructuring object - * @param {string} data.albumName the album id - * @param {string[]} data.fileIdsToRemove list of files - */ - removeFilesFromSharedAlbum(state, { albumName, fileIdsToRemove }) { - state.sharedAlbumsFiles = { - ...state.sharedAlbumsFiles, - [albumName]: state.sharedAlbumsFiles[albumName].filter(fileId => !fileIdsToRemove.includes(fileId)), - } - state.sharedAlbums[albumName].nbItems -= fileIdsToRemove.length - }, -} - -const getters = { - sharedAlbums: state => state.sharedAlbums, - sharedAlbumsFiles: state => state.sharedAlbumsFiles, -} - -const actions = { - /** - * Update files and albums - * - * @param {object} context vuex context - * @param {object} data destructuring object - * @param {Album[]} data.albums list of albums - */ - addSharedAlbums(context, { albums }) { - context.commit('addSharedAlbums', { albums }) - }, - - /** - * Add files to an album. - * - * @param {object} context vuex context - * @param {object} data destructuring object - * @param {string} data.albumName the album name - * @param {string[]} data.fileIdsToAdd list of files ids to add - */ - async addFilesToSharedAlbum(context, { albumName, fileIdsToAdd }) { - const semaphore = new Semaphore(5) - - context.commit('addFilesToSharedAlbum', { albumName, fileIdsToAdd }) - - const promises = fileIdsToAdd - .map(async (fileId) => { - const file = context.getters.files[fileId] - const album = context.getters.sharedAlbums[albumName] - const symbol = await semaphore.acquire() - - try { - await client.copyFile( - file.filename, - `${album.filename}/${file.basename}`, - ) - } catch (error) { - if (error.response.status !== 409) { // Already in the album. - context.commit('removeFilesFromSharedAlbum', { albumName, fileIdsToRemove: [fileId] }) - - logger.error(t('photos', 'Failed to add {fileBaseName} to shared album {albumName}.', { fileBaseName: file.basename, albumName }), error) - showError(t('photos', 'Failed to add {fileBaseName} to shared album {albumName}.', { fileBaseName: file.basename, albumName })) - } - } finally { - semaphore.release(symbol) - } - }) - - return Promise.all(promises) - }, - - /** - * Remove files to an album. - * - * @param {object} context vuex context - * @param {object} data destructuring object - * @param {string} data.albumName the album name - * @param {string[]} data.fileIdsToRemove list of files ids to remove - */ - async removeFilesFromSharedAlbum(context, { albumName, fileIdsToRemove }) { - const semaphore = new Semaphore(5) - - context.commit('removeFilesFromSharedAlbum', { albumName, fileIdsToRemove }) - - const promises = fileIdsToRemove - .map(async (fileId) => { - const file = context.getters.files[fileId] - const symbol = await semaphore.acquire() - - try { - await client.deleteFile(file.filename) - } catch (error) { - context.commit('addFilesToSharedAlbum', { albumName, fileIdsToAdd: [fileId] }) - - logger.error(t('photos', 'Failed to delete {fileBaseName}.', { fileBaseName: file.basename }), error) - showError(t('photos', 'Failed to delete {fileBaseName}.', { fileBaseName: file.basename })) - } finally { - semaphore.release(symbol) - } - }) - - return Promise.all(promises) - }, - - /** - * Delete an album. - * - * @param {object} context vuex context - * @param {object} data destructuring object - * @param {string} data.albumName the id of the album - */ - async deleteSharedAlbum(context, { albumName }) { - try { - const album = context.getters.sharedAlbums[albumName] - await client.deleteFile(album.filename) - context.commit('removeSharedAlbums', { albumNames: [albumName] }) - } catch (error) { - logger.error(t('photos', 'Failed to delete {albumName}.', { albumName }), error) - showError(t('photos', 'Failed to delete {albumName}.', { albumName })) - } - }, -} - -export default { state, mutations, getters, actions } diff --git a/src/views/PublicAlbumContent.vue b/src/views/PublicAlbumContent.vue index 052bb622..420f8f58 100644 --- a/src/views/PublicAlbumContent.vue +++ b/src/views/PublicAlbumContent.vue @@ -88,17 +88,6 @@ </NcButton> </NcEmptyContent> </CollectionContent> - - <!-- Modals --> - <NcModal v-if="showAddPhotosModal" - size="large" - :title="t('photos', 'Add photos to the album')" - @close="showAddPhotosModal = false"> - <FilesPicker :destination="album.basename" - :blacklist-ids="albumFileIds" - :loading="loadingAddFilesToAlbum" - @files-picked="handleFilesPicked" /> - </NcModal> </div> </template> @@ -119,7 +108,6 @@ import AbortControllerMixin from '../mixins/AbortControllerMixin.js' import CollectionContent from '../components/Collection/CollectionContent.vue' import HeaderNavigation from '../components/HeaderNavigation.vue' // import ActionDownload from '../components/Actions/ActionDownload.vue' -import FilesPicker from '../components/FilesPicker.vue' import { fetchAlbum, fetchAlbumContent } from '../services/Albums.js' import logger from '../services/logger.js' @@ -137,10 +125,8 @@ export default { NcActionButton, // NcActionSeparator, NcButton, - NcModal, CollectionContent, // ActionDownload, - FilesPicker, HeaderNavigation, }, |