diff options
Diffstat (limited to 'apps/files_versions/src')
-rw-r--r-- | apps/files_versions/src/components/Version.vue | 82 | ||||
-rw-r--r-- | apps/files_versions/src/components/VersionLabelDialog.vue | 4 | ||||
-rw-r--r-- | apps/files_versions/src/utils/versions.ts | 6 | ||||
-rw-r--r-- | apps/files_versions/src/views/VersionTab.vue | 64 |
4 files changed, 88 insertions, 68 deletions
diff --git a/apps/files_versions/src/components/Version.vue b/apps/files_versions/src/components/Version.vue index 177a9fef807..dc36e4134f9 100644 --- a/apps/files_versions/src/components/Version.vue +++ b/apps/files_versions/src/components/Version.vue @@ -11,7 +11,7 @@ <!-- Icon --> <template #icon> <div v-if="!(loadPreview || previewLoaded)" class="version__image" /> - <img v-else-if="(isCurrent || version.hasPreview) && !previewErrored" + <img v-else-if="version.previewUrl && !previewErrored" :src="version.previewUrl" alt="" decoding="async" @@ -31,18 +31,24 @@ <div class="version__info"> <div v-if="versionLabel" class="version__info__label" + data-cy-files-version-label :title="versionLabel"> {{ versionLabel }} </div> - <div v-if="versionAuthor" class="version__info"> + <div v-if="versionAuthor" + class="version__info" + data-cy-files-version-author-name> <span v-if="versionLabel">•</span> <NcAvatar class="avatar" :user="version.author" - :size="16" - :disable-menu="true" - :disable-tooltip="true" + :size="20" + disable-menu + disable-tooltip :show-user-status="false" /> - <div>{{ versionAuthor }}</div> + <div class="version__info__author_name" + :title="versionAuthor"> + {{ versionAuthor }} + </div> </div> </div> </template> @@ -53,7 +59,7 @@ <NcDateTime class="version__info__date" relative-time="short" :timestamp="version.mtime" /> - <!-- Separate dot to improve alignement --> + <!-- Separate dot to improve alignment --> <span>•</span> <span>{{ humanReadableSize }}</span> </div> @@ -114,29 +120,31 @@ import type { PropType } from 'vue' import type { Version } from '../utils/versions' +import { getCurrentUser } from '@nextcloud/auth' +import { Permission, formatFileSize } from '@nextcloud/files' +import { loadState } from '@nextcloud/initial-state' +import { t } from '@nextcloud/l10n' +import { joinPaths } from '@nextcloud/paths' +import { getRootUrl, generateUrl } from '@nextcloud/router' import { defineComponent } from 'vue' +import axios from '@nextcloud/axios' +import moment from '@nextcloud/moment' +import logger from '../utils/logger' + import BackupRestore from 'vue-material-design-icons/BackupRestore.vue' import Delete from 'vue-material-design-icons/Delete.vue' import Download from 'vue-material-design-icons/Download.vue' import FileCompare from 'vue-material-design-icons/FileCompare.vue' import ImageOffOutline from 'vue-material-design-icons/ImageOffOutline.vue' -import Pencil from 'vue-material-design-icons/Pencil.vue' - -import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js' -import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js' -import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js' -import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js' -import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js' -import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js' +import Pencil from 'vue-material-design-icons/PencilOutline.vue' -import moment from '@nextcloud/moment' -import { getRootUrl, generateOcsUrl } from '@nextcloud/router' -import { joinPaths } from '@nextcloud/paths' -import { loadState } from '@nextcloud/initial-state' -import { Permission, formatFileSize } from '@nextcloud/files' -import { translate as t } from '@nextcloud/l10n' -import axios from '@nextcloud/axios' +import NcActionButton from '@nextcloud/vue/components/NcActionButton' +import NcActionLink from '@nextcloud/vue/components/NcActionLink' +import NcAvatar from '@nextcloud/vue/components/NcAvatar' +import NcDateTime from '@nextcloud/vue/components/NcDateTime' +import NcListItem from '@nextcloud/vue/components/NcListItem' +import Tooltip from '@nextcloud/vue/directives/Tooltip' const hasPermission = (permissions: number, permission: number): boolean => (permissions & permission) !== 0 @@ -199,7 +207,7 @@ export default defineComponent({ previewLoaded: false, previewErrored: false, capabilities: loadState('core', 'capabilities', { files: { version_labeling: false, version_deletion: false } }), - versionAuthor: '', + versionAuthor: '' as string | null, } }, @@ -295,21 +303,26 @@ export default defineComponent({ }, async fetchDisplayName() { - // check to make sure that we have a valid author - in case database did not migrate, null author, etc. - if (this.version.author) { + this.versionAuthor = null + if (!this.version.author) { + return + } + + if (this.version.author === getCurrentUser()?.uid) { + this.versionAuthor = t('files_versions', 'You') + } else { try { - const { data } = await axios.get(generateOcsUrl(`/cloud/users/${this.version.author}`)) - this.versionAuthor = data.ocs.data.displayname - } catch (e) { - // Promise got rejected - default to null author to not try to load author profile - this.versionAuthor = null + const { data } = await axios.post(generateUrl('/displaynames'), { users: [this.version.author] }) + this.versionAuthor = data.users[this.version.author] + } catch (error) { + logger.warn('Could not load user display name', { error }) } } }, click() { if (!this.canView) { - window.location = this.downloadURL + window.location.href = this.downloadURL return } this.$emit('click', { version: this.version }) @@ -339,12 +352,19 @@ export default defineComponent({ gap: 0.5rem; color: var(--color-main-text); font-weight: 500; + overflow: hidden; &__label { font-weight: 700; // Fix overflow on narrow screens overflow: hidden; text-overflow: ellipsis; + min-width: 110px; + } + + &__author_name { + overflow: hidden; + text-overflow: ellipsis; } &__date { diff --git a/apps/files_versions/src/components/VersionLabelDialog.vue b/apps/files_versions/src/components/VersionLabelDialog.vue index 9a2ca59b80a..760780cae61 100644 --- a/apps/files_versions/src/components/VersionLabelDialog.vue +++ b/apps/files_versions/src/components/VersionLabelDialog.vue @@ -28,8 +28,8 @@ import { t } from '@nextcloud/l10n' import { defineComponent } from 'vue' import svgCheck from '@mdi/svg/svg/check.svg?raw' -import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js' -import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js' +import NcDialog from '@nextcloud/vue/components/NcDialog' +import NcTextField from '@nextcloud/vue/components/NcTextField' type Focusable = Vue & { focus: () => void } diff --git a/apps/files_versions/src/utils/versions.ts b/apps/files_versions/src/utils/versions.ts index b52f92ef462..6d5933f0bd9 100644 --- a/apps/files_versions/src/utils/versions.ts +++ b/apps/files_versions/src/utils/versions.ts @@ -28,7 +28,6 @@ export interface Version { type: string, // 'file' mtime: number, // Version creation date as a timestamp permissions: string, // Only readable: 'R' - hasPreview: boolean, // Whether the version has a preview previewUrl: string, // Preview URL of the version url: string, // Download URL of the version source: string, // The WebDAV endpoint of the ressource @@ -78,12 +77,12 @@ function formatVersion(version: any, fileInfo: any): Version { let previewUrl = '' if (mtime === fileInfo.mtime) { // Version is the current one - previewUrl = generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0', { + previewUrl = generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0&forceIcon=1&mimeFallback=1', { fileId: fileInfo.id, fileEtag: fileInfo.etag, }) } else { - previewUrl = generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', { + previewUrl = generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}&mimeFallback=1', { file: joinPaths(fileInfo.path, fileInfo.name), fileVersion: version.basename, }) @@ -102,7 +101,6 @@ function formatVersion(version: any, fileInfo: any): Version { type: version.type, mtime, permissions: 'R', - hasPreview: version.props['has-preview'] === 1, previewUrl, url: joinPaths('/remote.php/dav', version.filename), source: generateRemoteUrl('dav') + encodePath(version.filename), diff --git a/apps/files_versions/src/views/VersionTab.vue b/apps/files_versions/src/views/VersionTab.vue index 658b95c8e99..a643aef439d 100644 --- a/apps/files_versions/src/views/VersionTab.vue +++ b/apps/files_versions/src/views/VersionTab.vue @@ -4,28 +4,27 @@ --> <template> <div class="versions-tab__container"> - <VirtualScrolling :sections="sections" + <VirtualScrolling v-slot="{ visibleSections }" + :sections="sections" :header-height="0"> - <template slot-scope="{visibleSections}"> - <ul data-files-versions-versions-list> - <template v-if="visibleSections.length === 1"> - <Version v-for="(row) of visibleSections[0].rows" - :key="row.items[0].mtime" - :can-view="canView" - :can-compare="canCompare" - :load-preview="isActive" - :version="row.items[0]" - :file-info="fileInfo" - :is-current="row.items[0].mtime === fileInfo.mtime" - :is-first-version="row.items[0].mtime === initialVersionMtime" - @click="openVersion" - @compare="compareVersion" - @restore="handleRestore" - @label-update-request="handleLabelUpdateRequest(row.items[0])" - @delete="handleDelete" /> - </template> - </ul> - </template> + <ul :aria-label="t('files_versions', 'File versions')" data-files-versions-versions-list> + <template v-if="visibleSections.length === 1"> + <Version v-for="(row) of visibleSections[0].rows" + :key="row.items[0].mtime" + :can-view="canView" + :can-compare="canCompare" + :load-preview="isActive" + :version="row.items[0]" + :file-info="fileInfo" + :is-current="row.items[0].mtime === fileInfo.mtime" + :is-first-version="row.items[0].mtime === initialVersionMtime" + @click="openVersion" + @compare="compareVersion" + @restore="handleRestore" + @label-update-request="handleLabelUpdateRequest(row.items[0])" + @delete="handleDelete" /> + </template> + </ul> <NcLoadingIcon v-if="loading" slot="loader" class="files-list-viewer__loader" /> </VirtualScrolling> <VersionLabelDialog v-if="editedVersion" @@ -38,11 +37,11 @@ <script> import path from 'path' +import { getCurrentUser } from '@nextcloud/auth' import { showError, showSuccess } from '@nextcloud/dialogs' import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus' -import { getCurrentUser } from '@nextcloud/auth' -import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' -import isMobile from '@nextcloud/vue/dist/Mixins/isMobile.js' +import { useIsMobile } from '@nextcloud/vue/composables/useIsMobile' +import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon' import { fetchVersions, deleteVersion, restoreVersion, setVersionLabel } from '../utils/versions.ts' import Version from '../components/Version.vue' @@ -57,9 +56,13 @@ export default { VersionLabelDialog, NcLoadingIcon, }, - mixins: [ - isMobile, - ], + + setup() { + return { + isMobile: useIsMobile(), + } + }, + data() { return { fileInfo: null, @@ -200,7 +203,7 @@ export default { try { await restoreVersion(version) - if (version.label !== '') { + if (version.label) { showSuccess(t('files_versions', `${version.label} restored`)) } else if (version.mtime === this.initialVersionMtime) { showSuccess(t('files_versions', 'Initial version restored')) @@ -274,13 +277,12 @@ export default { return } - // Versions previews are too small for our use case, so we override hasPreview and previewUrl + // Versions previews are too small for our use case, so we override previewUrl // which makes the viewer render the original file. // We also point to the original filename if the version is the current one. const versions = this.versions.map(version => ({ ...version, filename: version.mtime === this.fileInfo.mtime ? path.join('files', getCurrentUser()?.uid ?? '', this.fileInfo.path, this.fileInfo.name) : version.filename, - hasPreview: false, previewUrl: undefined, })) @@ -291,7 +293,7 @@ export default { }, compareVersion({ version }) { - const versions = this.versions.map(version => ({ ...version, hasPreview: false, previewUrl: undefined })) + const versions = this.versions.map(version => ({ ...version, previewUrl: undefined })) OCA.Viewer.compare(this.viewerFileInfo, versions.find(v => v.source === version.source)) }, |