Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/photos.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/views/AlbumContent.vue')
-rw-r--r--src/views/AlbumContent.vue478
1 files changed, 165 insertions, 313 deletions
diff --git a/src/views/AlbumContent.vue b/src/views/AlbumContent.vue
index e8ba63b3..75655a05 100644
--- a/src/views/AlbumContent.vue
+++ b/src/views/AlbumContent.vue
@@ -20,132 +20,104 @@
-
-->
<template>
- <!-- Errors handlers-->
- <NcEmptyContent v-if="album === undefined && !loadingAlbums" class="empty-content-with-illustration">
- <template #icon>
- <!-- eslint-disable-next-line vue/no-v-html -->
- <span class="empty-content-illustration" v-html="FolderIllustration" />
- </template>
- {{ t('photos', 'This album does not exist') }}
- </NcEmptyContent>
-
- <NcEmptyContent v-else-if="errorFetchingFiles || errorFetchingAlbums">
- <template #icon>
- <AlertCircle />
- </template>
- {{ t('photos', 'An error occurred') }}
- </NcEmptyContent>
-
- <div v-else class="album">
- <HeaderNavigation key="navigation"
- :loading="loadingFiles"
- :params="{ albumName }"
- :path="'/' + albumName"
- :title="albumName"
- @refresh="fetchAlbumContent">
- <!-- <UploadPicker :accept="allowedMimes"
+ <div>
+ <CollectionContent v-if="true"
+ ref="collectionContent"
+ :collection="album"
+ :collection-file-ids="albumFileIds"
+ :semaphore="semaphore"
+ :loading="loadingAlbums || loadingFiles"
+ :error="errorFetchingAlbums || errorFetchingFiles">
+ <!-- Header -->
+ <HeaderNavigation key="navigation"
+ slot="header"
+ slot-scope="{selectedFileIds}"
+ :loading="loadingFiles"
+ :params="{ albumName }"
+ :path="'/' + albumName"
+ :title="albumName"
+ @refresh="fetchAlbumContent">
+ <!-- <UploadPicker :accept="allowedMimes"
:destination="folder.filename"
:multiple="true"
@uploaded="onUpload" /> -->
- <div v-if="album.location !== ''" class="album__location">
- <MapMarker />{{ album.location }}
- </div>
-
- <template #right>
- <NcButton v-if="album.nbItems !== 0"
- type="tertiary"
- :aria-label="t('photos', 'Add photos to this album')"
- @click="showAddPhotosModal = true">
- <template #icon>
- <Plus />
- </template>
- </NcButton>
- <NcActions :force-menu="true">
- <NcActionButton :close-after-click="true"
- :aria-label="t('photos', 'Edit album details')"
- @click="showEditAlbumForm = true">
- {{ t('photos', 'Edit album details') }}
- <Pencil slot="icon" />
- </NcActionButton>
- <NcActionButton v-if="albumFileIds.length > 0"
- :close-after-click="true"
- :aria-label="t('photos', 'Download all files in album')"
- @click="downloadAllFiles">
- {{ t('photos', 'Download all files in album') }}
- <DownloadMultiple slot="icon" />
- </NcActionButton>
- <template v-if="selectedFileIds.length > 0">
+ <div v-if="album.location !== ''" slot="subtitle" class="album__location">
+ <MapMarker />{{ album.location }}
+ </div>
+ <template v-if="album !== undefined"
+ slot="right">
+ <NcButton v-if="album.nbItems !== 0"
+ type="tertiary"
+ :aria-label="t('photos', 'Add photos to this album')"
+ @click="showAddPhotosModal = true">
+ <template #icon>
+ <Plus />
+ </template>
+ </NcButton>
+
+ <NcButton v-if="sharingEnabled"
+ type="tertiary"
+ :aria-label="t('photos', 'Manage collaborators for this album')"
+ @click="showManageCollaboratorView = true">
+ <ShareVariant slot="icon" />
+ </NcButton>
+
+ <NcActions :aria-label="t('photos', 'Open actions menu')">
<NcActionButton :close-after-click="true"
- :aria-label="t('photos', 'Download selection')"
- @click="downloadSelection">
- {{ t('photos', 'Download selected files') }}
- <Download slot="icon" />
- </NcActionButton>
- <NcActionButton v-if="shouldFavoriteSelection"
- :close-after-click="true"
- :aria-label="t('photos', 'Mark selection as favorite')"
- @click="favoriteSelection">
- {{ t('photos', 'Favorite') }}
- <Star slot="icon" />
- </NcActionButton>
- <NcActionButton v-else
- :close-after-click="true"
- :aria-label="t('photos', 'Remove selection from favorites')"
- @click="unFavoriteSelection">
- {{ t('photos', 'Remove from favorites') }}
- <Star slot="icon" />
+ :aria-label="t('photos', 'Edit album details')"
+ @click="showEditAlbumForm = true">
+ {{ t('photos', 'Edit album details') }}
+ <Pencil slot="icon" />
</NcActionButton>
+
+ <ActionDownload v-if="albumFileIds.length > 0"
+ :selected-file-ids="albumFileIds"
+ :title="t('photos', 'Download all files in album')">
+ <DownloadMultiple slot="icon" />
+ </ActionDownload>
+
<NcActionButton :close-after-click="true"
- @click="handleRemoveFilesFromAlbum(selectedFileIds)">
- {{ n('photos', 'Remove item from album', 'Remove selection from album', selection.length) }}
- <template #icon>
- <Close />
- </template>
+ @click="handleDeleteAlbum">
+ {{ t('photos', 'Delete album') }}
+ <Delete slot="icon" />
</NcActionButton>
- </template>
- <NcActionButton :close-after-click="true"
- @click="handleDeleteAlbum">
- {{ t('photos', 'Delete album') }}
- <Delete slot="icon" />
- </NcActionButton>
- </NcActions>
- </template>
- </HeaderNavigation>
-
- <div v-if="album.nbItems === 0 && !(loadingFiles || loadingAlbums)" class="album__empty">
- <NcEmptyContent>
- <template #icon>
- <ImagePlus />
- </template>
- <template #desc>
- {{ t('photos', "This album doesn't have any photos or videos yet!") }}
- </template>
- </NcEmptyContent>
- <Button class="album__empty__button"
- type="primary"
- :aria-label="t('photos', 'Add photos to this album')"
- @click="showAddPhotosModal = true">
- <template #icon>
- <Plus />
+ <template v-if="selectedFileIds.length > 0">
+ <NcActionSeparator />
+
+ <ActionDownload :selected-file-ids="selectedFileIds" :title="t('photos', 'Download selected files')">
+ <Download slot="icon" />
+ </ActionDownload>
+
+ <ActionFavorite :selected-file-ids="selectedFileIds" />
+
+ <NcActionButton :close-after-click="true"
+ @click="handleRemoveFilesFromAlbum(selectedFileIds)">
+ {{ t('photos', 'Remove selection from album') }}
+ <Close slot="icon" />
+ </NcActionButton>
+ </template>
+ </NcActions>
</template>
- {{ t('photos', "Add") }}
- </Button>
- </div>
-
- <FilesListViewer v-else
- class="album__photos"
- :file-ids="albumFileIds"
- :base-height="isMobile ? 120 : 200">
- <File slot-scope="{file, visibility}"
- :file="files[file.id]"
- :allow-selection="true"
- :selected="selection[file.id] === true"
- :visibility="visibility"
- :semaphore="semaphore"
- @click="openViewer"
- @select-toggled="onFileSelectToggle" />
- </FilesListViewer>
+ </HeaderNavigation>
+
+ <!-- No content -->
+ <NcEmptyContent v-if="album !== undefined && album.nbItems === 0 && !(loadingFiles || loadingAlbums)"
+ slot="empty-content"
+ :title="t('photos', 'This album doesn\'t have any photos or videos yet!')"
+ class="album__empty">
+ <ImagePlus slot="icon" />
+
+ <NcButton slot="action"
+ class="album__empty__button"
+ type="primary"
+ :aria-label="t('photos', 'Add photos to this album')"
+ @click="showAddPhotosModal = true">
+ <Plus slot="icon" />
+ {{ t('photos', "Add") }}
+ </NcButton>
+ </NcEmptyContent>
+ </CollectionContent>
<NcModal v-if="showAddPhotosModal"
size="large"
@@ -153,14 +125,27 @@
@close="showAddPhotosModal = false">
<FilesPicker :destination="album.basename"
:blacklist-ids="albumFileIds"
- :loading="loadingAddFilesToAlbum"
@files-picked="handleFilesPicked" />
</NcModal>
- <NcModal v-else-if="showShareModal"
- :title="t('photos', 'Share the album')"
- @close="showShareModal = false">
- <ShareAlbumForm @albumShared="showShareModal = false" />
+ <NcModal v-if="showManageCollaboratorView"
+ :title="t('photos', 'Manager collaborators')"
+ @close="showManageCollaboratorView = false">
+ <CollaboratorsSelectionForm :album-name="album.basename"
+ :collaborators="album.collaborators"
+ :public-link="album.publicLink">
+ <template slot-scope="{collaborators}">
+ <NcButton :aria-label="t('photos', 'Save collaborators for this album.')"
+ type="primary"
+ :disabled="loadingAddCollaborators"
+ @click="handleSetCollaborators(collaborators)">
+ <template #icon>
+ <NcLoadingIcon v-if="loadingAddCollaborators" />
+ </template>
+ {{ t('photos', 'Save') }}
+ </NcButton>
+ </template>
+ </CollaboratorsSelectionForm>
</NcModal>
<NcModal v-if="showEditAlbumForm"
@@ -173,69 +158,69 @@
<script>
import { mapActions, mapGetters } from 'vuex'
-import { NcActions, NcActionButton, NcButton, NcModal, NcEmptyContent, isMobile } from '@nextcloud/vue'
-import { getCurrentUser } from '@nextcloud/auth'
import MapMarker from 'vue-material-design-icons/MapMarker'
+import ShareVariant from 'vue-material-design-icons/ShareVariant'
import Plus from 'vue-material-design-icons/Plus'
import Pencil from 'vue-material-design-icons/Pencil'
import Delete from 'vue-material-design-icons/Delete'
import ImagePlus from 'vue-material-design-icons/ImagePlus'
-import AlertCircle from 'vue-material-design-icons/AlertCircle'
-import Star from 'vue-material-design-icons/Star'
import Close from 'vue-material-design-icons/Close'
import Download from 'vue-material-design-icons/Download'
import DownloadMultiple from 'vue-material-design-icons/DownloadMultiple'
-import { genFileInfo } from '../utils/fileUtils.js'
-import AbortControllerMixin from '../mixins/AbortControllerMixin.js'
+import { NcActions, NcActionButton, NcButton, NcModal, NcEmptyContent, NcActionSeparator, NcLoadingIcon, isMobile } from '@nextcloud/vue'
+import { getCurrentUser } from '@nextcloud/auth'
+import { generateRemoteUrl } from '@nextcloud/router'
+
import FetchAlbumsMixin from '../mixins/FetchAlbumsMixin.js'
import FetchFilesMixin from '../mixins/FetchFilesMixin.js'
-import FilesSelectionMixin from '../mixins/FilesSelectionMixin.js'
-
+import AbortControllerMixin from '../mixins/AbortControllerMixin.js'
+import HeaderNavigation from '../components/HeaderNavigation.vue'
+import FilesPicker from '../components/FilesPicker.vue'
+import CollectionContent from '../components/Collection/CollectionContent.vue'
+import ActionFavorite from '../components/Actions/ActionFavorite.vue'
+import ActionDownload from '../components/Actions/ActionDownload.vue'
+import CollaboratorsSelectionForm from '../components/Albums/CollaboratorsSelectionForm.vue'
+import AlbumForm from '../components/Albums/AlbumForm.vue'
+import logger from '../services/logger.js'
import client from '../services/DavClient.js'
import DavRequest from '../services/DavRequest.js'
-import FolderIllustration from '../assets/Illustrations/folder.svg'
-import logger from '../services/logger.js'
-
-import AlbumForm from '../components/AlbumForm.vue'
-import File from '../components/File.vue'
-import FilesListViewer from '../components/FilesListViewer.vue'
-import FilesPicker from '../components/FilesPicker.vue'
-import HeaderNavigation from '../components/HeaderNavigation.vue'
-import ShareAlbumForm from '../components/ShareAlbumForm.vue'
+import { genFileInfo } from '../utils/fileUtils.js'
export default {
name: 'AlbumContent',
components: {
- AlbumForm,
- AlertCircle,
+ MapMarker,
+ ShareVariant,
+ Plus,
+ Pencil,
Close,
Delete,
Download,
DownloadMultiple,
- File,
- FilesListViewer,
FilesPicker,
HeaderNavigation,
ImagePlus,
- MapMarker,
- NcActionButton,
+ NcEmptyContent,
NcActions,
+ NcActionButton,
NcButton,
- NcEmptyContent,
NcModal,
- Pencil,
- Plus,
- ShareAlbumForm,
- Star,
+ NcLoadingIcon,
+ NcActionSeparator,
+ CollectionContent,
+ ActionFavorite,
+ ActionDownload,
+ AlbumForm,
+ CollaboratorsSelectionForm,
},
mixins: [
AbortControllerMixin,
FetchAlbumsMixin,
FetchFilesMixin,
- FilesSelectionMixin,
+ AbortControllerMixin,
isMobile,
],
@@ -249,22 +234,19 @@ export default {
data() {
return {
showAddPhotosModal: false,
- showShareModal: false,
+ showManageCollaboratorView: false,
showEditAlbumForm: false,
- FolderIllustration,
- loadingCount: 0,
- loadingAddFilesToAlbum: false,
+ loadingAddCollaborators: false,
}
},
computed: {
...mapGetters([
- 'files',
'albumsFiles',
]),
/**
- * @return {string[]} The album information for the current albumName.
+ * @return {object} The album information for the current albumName.
*/
album() {
return this.albums[this.albumName] || {}
@@ -277,10 +259,11 @@ export default {
return this.albumsFiles[this.albumName] || []
},
- /** @type {boolean} */
- shouldFavoriteSelection() {
- // Favorite all selection if at least one file is not on the favorites.
- return this.selectedFileIds.some((fileId) => this.$store.state.files.files[fileId].favorite === 0)
+ /**
+ * @return {boolean} Whether sharing is enabled.
+ */
+ sharingEnabled() {
+ return OC.Share !== undefined
},
},
@@ -296,8 +279,7 @@ export default {
'deleteAlbum',
'addFilesToAlbum',
'removeFilesFromAlbum',
- 'toggleFavoriteForFiles',
- 'downloadFiles',
+ 'updateAlbum',
]),
async fetchAlbumContent() {
@@ -324,7 +306,8 @@ export default {
const fetchedFiles = response.data
.map(file => genFileInfo(file))
- .map(file => ({ ...file, filename: file.realpath.replace(`/${getCurrentUser().uid}/files`, '') }))
+ // For the Viewer.
+ .map(file => ({ ...file, source: generateRemoteUrl(`dav${file.filename}`) }))
const fileIds = fetchedFiles
.map(file => file.fileid)
@@ -358,16 +341,6 @@ export default {
return []
},
- openViewer(fileId) {
- const file = this.files[fileId]
- OCA.Viewer.open({
- fileInfo: file,
- list: this.albumFileIds.map(fileId => this.files[fileId]).filter(file => !file.sectionHeader),
- loadMore: file.loadMore ? async () => await file.loadMore(true) : () => [],
- canLoop: file.canLoop,
- })
- },
-
redirectToNewName({ album }) {
this.showEditAlbumForm = false
@@ -382,81 +355,31 @@ export default {
},
async handleFilesPicked(fileIds) {
- try {
- this.loadingAddFilesToAlbum = true
- await this.addFilesToAlbum({ albumName: this.albumName, fileIdsToAdd: fileIds })
- this.showAddPhotosModal = false
- } catch (error) {
- logger.error(error)
- } finally {
- this.loadingAddFilesToAlbum = false
- }
+ this.showAddPhotosModal = false
+ await this.addFilesToAlbum({ albumName: this.albumName, fileIdsToAdd: fileIds })
+ // Re-fetch album content to have the proper filenames.
+ await this.fetchAlbumContent()
},
async handleRemoveFilesFromAlbum(fileIds) {
- try {
- this.loadingCount++
- await this.removeFilesFromAlbum({ albumName: this.albumName, fileIdsToRemove: fileIds })
- } catch (error) {
- logger.error(error)
- } finally {
- this.loadingCount--
- }
+ this.$refs.collectionContent.onUncheckFiles(fileIds)
+ await this.removeFilesFromAlbum({ albumName: this.albumName, fileIdsToRemove: fileIds })
},
async handleDeleteAlbum() {
- try {
- this.loadingCount++
- await this.deleteAlbum({ albumName: this.albumName })
- this.$router.push('/albums')
- } catch (error) {
- logger.error(error)
- } finally {
- this.loadingCount--
- }
- },
-
- async favoriteSelection() {
- try {
- this.loadingCount++
- await this.toggleFavoriteForFiles({ fileIds: this.selectedFileIds, favoriteState: true })
- } catch (error) {
- logger.error(error)
- } finally {
- this.loadingCount--
- }
- },
-
- async unFavoriteSelection() {
- try {
- this.loadingCount++
- await this.toggleFavoriteForFiles({ fileIds: this.selectedFileIds, favoriteState: false })
- } catch (error) {
- logger.error(error)
- } finally {
- this.loadingCount--
- }
+ await this.deleteAlbum({ albumName: this.albumName })
+ this.$router.push('/albums')
},
- async downloadAllFiles() {
+ async handleSetCollaborators(collaborators) {
try {
- this.loadingCount++
- await this.downloadFiles(this.albumFileIds)
+ this.loadingAddCollaborators = true
+ this.showManageCollaboratorView = false
+ await this.updateAlbum({ albumName: this.albumName, properties: { collaborators } })
} catch (error) {
logger.error(error)
} finally {
- this.loadingCount--
- }
- },
-
- async downloadSelection() {
- try {
- this.loadingCount++
- await this.downloadFiles(this.selectedFileIds)
- } catch (error) {
- logger.error(error)
- } finally {
- this.loadingCount--
+ this.loadingAddCollaborators = false
}
},
},
@@ -464,25 +387,8 @@ export default {
</script>
<style lang="scss" scoped>
.album {
- display: flex;
- flex-direction: column;
- height: 100%;
-
- &__empty {
- display: flex;
- flex-direction: column;
- align-items: center;
-
- &__button {
- margin-top: 32px;
- }
-
- }
-
- &__location {
- margin-left: -4px;
- display: flex;
- color: var(--color-text-lighter);
+ &__title {
+ width: 100%;
}
&__name {
@@ -491,64 +397,10 @@ export default {
text-overflow: ellipsis;
}
- &__header {
+ &__location {
+ margin-left: -4px;
display: flex;
- height: 60px;
- align-items: center;
- justify-content: space-between;
- position: sticky;
- z-index: 3;
- background: var(--color-main-background);
- padding: 8px 64px 32px 64px;
- box-sizing: content-box;
-
- @media only screen and (max-width: 1200px) {
- padding: 8px 48px 32px 48px;
- }
-
- &__left {
- height: 100%;
- display: flex;
- align-items: center;
- min-width: 0;
- }
-
- &__title {
- min-width: 0;
- }
-
- &__loader {
- margin-left: 32px;
- }
-
- &__actions {
- display: flex;
- align-items: center;
-
- button {
- margin-left: 16px;
- }
- }
- }
-
- &__photos {
- height: calc(100% - 60px);
- min-height: 0; // Prevent it from overflowing in a flex context.
- padding: 0 64px;
-
- @media only screen and (max-width: 1200px) {
- padding: 0 4px;
- }
- }
-}
-
-.empty-content-with-illustration ::v-deep .empty-content__icon {
- width: 200px;
- height: 200px;
-
- svg {
- width: 200px;
- height: 200px;
+ color: var(--color-text-lighter);
}
}
</style>