From 60260bb58e22a9309c126d54441e0ac28d2b140f Mon Sep 17 00:00:00 2001 From: John Molakvoæ Date: Thu, 12 Oct 2023 09:44:53 +0200 Subject: chore(files): split FileEntry Preview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ --- apps/files/src/components/FavoriteIcon.vue | 86 --------- apps/files/src/components/FileEntry.vue | 164 +--------------- .../src/components/FileEntry/FavoriteIcon.vue | 86 +++++++++ .../src/components/FileEntry/FileEntryPreview.vue | 211 +++++++++++++++++++++ apps/files/src/components/FilesListVirtual.vue | 21 +- 5 files changed, 324 insertions(+), 244 deletions(-) delete mode 100644 apps/files/src/components/FavoriteIcon.vue create mode 100644 apps/files/src/components/FileEntry/FavoriteIcon.vue create mode 100644 apps/files/src/components/FileEntry/FileEntryPreview.vue (limited to 'apps/files/src') diff --git a/apps/files/src/components/FavoriteIcon.vue b/apps/files/src/components/FavoriteIcon.vue deleted file mode 100644 index 6eb1fbd8edd..00000000000 --- a/apps/files/src/components/FavoriteIcon.vue +++ /dev/null @@ -1,86 +0,0 @@ - - - - - diff --git a/apps/files/src/components/FileEntry.vue b/apps/files/src/components/FileEntry.vue index f1606d218c2..1a1bf6d9baf 100644 --- a/apps/files/src/components/FileEntry.vue +++ b/apps/files/src/components/FileEntry.vue @@ -48,36 +48,10 @@ - - - - - - - - - - - - - +
import type { PropType } from 'vue' -import { emit, subscribe } from '@nextcloud/event-bus' +import { emit } from '@nextcloud/event-bus' import { extname, join } from 'path' -import { generateUrl } from '@nextcloud/router' import { getFileActions, DefaultType, FileType, formatFileSize, Permission, Folder, File as NcFile, FileAction, NodeStatus, Node } from '@nextcloud/files' import { getUploader } from '@nextcloud/upload' +import { loadState } from '@nextcloud/initial-state' import { showError, showSuccess } from '@nextcloud/dialogs' import { translate as t } from '@nextcloud/l10n' -import { Type as ShareType } from '@nextcloud/sharing' import { vOnClickOutside } from '@vueuse/components' import axios from '@nextcloud/axios' import moment from '@nextcloud/moment' import Vue from 'vue' -import AccountGroupIcon from 'vue-material-design-icons/AccountGroup.vue' -import FileIcon from 'vue-material-design-icons/File.vue' -import FolderIcon from 'vue-material-design-icons/Folder.vue' -import FolderOpenIcon from 'vue-material-design-icons/FolderOpen.vue' -import KeyIcon from 'vue-material-design-icons/Key.vue' -import TagIcon from 'vue-material-design-icons/Tag.vue' -import LinkIcon from 'vue-material-design-icons/Link.vue' -import NetworkIcon from 'vue-material-design-icons/Network.vue' -import AccountPlusIcon from 'vue-material-design-icons/AccountPlus.vue' import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' import NcActions from '@nextcloud/vue/dist/Components/NcActions.js' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' @@ -229,11 +193,9 @@ import { useFilesStore } from '../store/files.ts' import { useKeyboardStore } from '../store/keyboard.ts' import { useRenamingStore } from '../store/renaming.ts' import { useSelectionStore } from '../store/selection.ts' -import { useUserConfigStore } from '../store/userconfig.ts' import CustomElementRender from './CustomElementRender.vue' -import FavoriteIcon from './FavoriteIcon.vue' +import FileEntryPreview from './FileEntry/FileEntryPreview.vue' import logger from '../logger.js' -import { loadState } from '@nextcloud/initial-state' // The registered actions list const actions = getFileActions() @@ -246,23 +208,14 @@ export default Vue.extend({ name: 'FileEntry', components: { - AccountGroupIcon, - AccountPlusIcon, CustomElementRender, - FavoriteIcon, - FileIcon, - FolderIcon, - FolderOpenIcon, - KeyIcon, - LinkIcon, + FileEntryPreview, NcActionButton, NcActions, NcCheckboxRadioSwitch, NcIconSvgWrapper, NcLoadingIcon, NcTextField, - NetworkIcon, - TagIcon, }, props: { @@ -303,7 +256,6 @@ export default Vue.extend({ const keyboardStore = useKeyboardStore() const renamingStore = useRenamingStore() const selectionStore = useSelectionStore() - const userConfigStore = useUserConfigStore() return { actionsMenuStore, draggingStore, @@ -311,13 +263,11 @@ export default Vue.extend({ keyboardStore, renamingStore, selectionStore, - userConfigStore, } }, data() { return { - backgroundFailed: undefined, loading: '', dragover: false, @@ -326,9 +276,6 @@ export default Vue.extend({ }, computed: { - userConfig() { - return this.userConfigStore.userConfig - }, currentView() { return this.$navigation.active @@ -418,43 +365,6 @@ export default Vue.extend({ return '' }, - folderOverlay() { - if (this.source.type !== FileType.Folder) { - return null - } - - // Encrypted folders - if (this.source?.attributes?.['is-encrypted'] === 1) { - return KeyIcon - } - - // System tags - if (this.source?.attributes?.['is-tag']) { - return TagIcon - } - - // Link and mail shared folders - const shareTypes = Object.values(this.source?.attributes?.['share-types'] || {}).flat() as number[] - if (shareTypes.some(type => type === ShareType.SHARE_TYPE_LINK || type === ShareType.SHARE_TYPE_EMAIL)) { - return LinkIcon - } - - // Shared folders - if (shareTypes.length > 0) { - return AccountPlusIcon - } - - switch (this.source?.attributes?.['mount-type']) { - case 'external': - case 'external-session': - return NetworkIcon - case 'group': - return AccountGroupIcon - } - - return null - }, - linkTo() { if (this.source.attributes.failed) { return { @@ -495,38 +405,6 @@ export default Vue.extend({ return this.selectedFiles.includes(this.fileid) }, - cropPreviews() { - return this.userConfig.crop_image_previews - }, - previewUrl() { - if (this.source.type === FileType.Folder) { - return null - } - - if (this.backgroundFailed === true) { - return null - } - - try { - const previewUrl = this.source.attributes.previewUrl - || generateUrl('/core/preview?fileId={fileid}', { - fileid: this.fileid, - }) - const url = new URL(window.location.origin + previewUrl) - - // Request tiny previews - url.searchParams.set('x', '32') - url.searchParams.set('y', '32') - url.searchParams.set('mimeFallback', 'true') - - // Handle cropping - url.searchParams.set('a', this.cropPreviews === true ? '0' : '1') - return url.href - } catch (e) { - return null - } - }, - // Sorted actions that are enabled for this node enabledActions() { if (this.source.attributes.failed) { @@ -583,10 +461,6 @@ export default Vue.extend({ uniqueId() { return hashCode(this.source.source) }, - - isFavorite() { - return this.source.attributes.favorite === 1 - }, isLoading() { return this.source.status === NodeStatus.LOADING }, @@ -675,11 +549,7 @@ export default Vue.extend({ // Reset loading state this.loading = '' - // Reset background state - this.backgroundFailed = undefined - if (this.$refs.previewImg) { - this.$refs.previewImg.src = '' - } + this.$refs.preview.reset() // Close menu this.openedMenu = false @@ -1066,22 +936,6 @@ tr { background-color: var(--color-background-dark); } } - -// Folder overlay -.files-list__row-icon-overlay { - position: absolute; - max-height: 18px; - max-width: 18px; - color: var(--color-main-background); - // better alignment with the folder icon - margin-top: 2px; -} - -/* Preview not loaded animation effect */ -.files-list__row-icon-preview:not(.files-list__row-icon-preview--loaded) { - background: var(--color-loading-dark); - // animation: preview-gradient-fade 1.2s ease-in-out infinite; -} diff --git a/apps/files/src/components/FileEntry/FileEntryPreview.vue b/apps/files/src/components/FileEntry/FileEntryPreview.vue new file mode 100644 index 00000000000..7766980b144 --- /dev/null +++ b/apps/files/src/components/FileEntry/FileEntryPreview.vue @@ -0,0 +1,211 @@ + + + + diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index c5ff9e663a3..914cfa7ec4d 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -465,10 +465,15 @@ export default Vue.extend({ width: var(--icon-preview-size); height: var(--icon-preview-size); border-radius: var(--border-radius); - background-repeat: no-repeat; // Center and contain the preview - background-position: center; - background-size: contain; + object-fit: contain; + object-position: center; + + /* Preview not loaded animation effect */ + &:not(.files-list__row-icon-preview--loaded) { + background: var(--color-loading-dark); + // animation: preview-gradient-fade 1.2s ease-in-out infinite; + } } &-favorite { @@ -476,6 +481,16 @@ export default Vue.extend({ top: 0px; right: -10px; } + + // Folder overlay + &-overlay { + position: absolute; + max-height: 18px; + max-width: 18px; + color: var(--color-main-background); + // better alignment with the folder icon + margin-top: 2px; + } } // Entry link -- cgit v1.2.3