mirror of
https://github.com/nextcloud/server.git
synced 2026-06-14 19:20:35 -04:00
Merge pull request #39119 from nextcloud/artonge/backport/stable27/38905
[stable27] Reduce load of files versions preview loading
This commit is contained in:
commit
d119cb132a
13 changed files with 51 additions and 12 deletions
|
|
@ -28,6 +28,7 @@ export default class Tab {
|
|||
_icon
|
||||
_iconSvgSanitized
|
||||
_mount
|
||||
_setIsActive
|
||||
_update
|
||||
_destroy
|
||||
_enabled
|
||||
|
|
@ -42,12 +43,13 @@ export default class Tab {
|
|||
* @param {?string} options.icon the icon css class
|
||||
* @param {?string} options.iconSvg the icon in svg format
|
||||
* @param {Function} options.mount function to mount the tab
|
||||
* @param {Function} [options.setIsActive] function to forward the active state of the tab
|
||||
* @param {Function} options.update function to update the tab
|
||||
* @param {Function} options.destroy function to destroy the tab
|
||||
* @param {Function} [options.enabled] define conditions whether this tab is active. Must returns a boolean
|
||||
* @param {Function} [options.scrollBottomReached] executed when the tab is scrolled to the bottom
|
||||
*/
|
||||
constructor({ id, name, icon, iconSvg, mount, update, destroy, enabled, scrollBottomReached } = {}) {
|
||||
constructor({ id, name, icon, iconSvg, mount, setIsActive, update, destroy, enabled, scrollBottomReached } = {}) {
|
||||
if (enabled === undefined) {
|
||||
enabled = () => true
|
||||
}
|
||||
|
|
@ -68,6 +70,9 @@ export default class Tab {
|
|||
if (typeof mount !== 'function') {
|
||||
throw new Error('The mount argument should be a function')
|
||||
}
|
||||
if (setIsActive !== undefined && typeof setIsActive !== 'function') {
|
||||
throw new Error('The setIsActive argument should be a function')
|
||||
}
|
||||
if (typeof update !== 'function') {
|
||||
throw new Error('The update argument should be a function')
|
||||
}
|
||||
|
|
@ -85,6 +90,7 @@ export default class Tab {
|
|||
this._name = name
|
||||
this._icon = icon
|
||||
this._mount = mount
|
||||
this._setIsActive = setIsActive
|
||||
this._update = update
|
||||
this._destroy = destroy
|
||||
this._enabled = enabled
|
||||
|
|
@ -119,6 +125,10 @@ export default class Tab {
|
|||
return this._mount
|
||||
}
|
||||
|
||||
get setIsActive() {
|
||||
return this._setIsActive || (() => undefined)
|
||||
}
|
||||
|
||||
get update() {
|
||||
return this._update
|
||||
}
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ export default {
|
|||
*/
|
||||
setActiveTab(id) {
|
||||
OCA.Files.Sidebar.setActiveTab(id)
|
||||
this.tabs.forEach(tab => tab.setIsActive(id === tab.id))
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -453,6 +454,7 @@ export default {
|
|||
if (this.$refs.tabs) {
|
||||
this.$refs.tabs.updateTabs()
|
||||
}
|
||||
this.setActiveTab(this.Sidebar.activeTab || this.tabs[0].id)
|
||||
})
|
||||
} catch (error) {
|
||||
this.error = t('files', 'Error while loading the file data')
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OC\AppFramework\Http\Request;
|
||||
use OCA\DAV\Connector\Sabre\FilesPlugin;
|
||||
use OCP\IPreview;
|
||||
use OCP\IRequest;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\INode;
|
||||
|
|
@ -39,12 +41,12 @@ use Sabre\HTTP\ResponseInterface;
|
|||
|
||||
class Plugin extends ServerPlugin {
|
||||
private Server $server;
|
||||
private IRequest $request;
|
||||
|
||||
public const VERSION_LABEL = '{http://nextcloud.org/ns}version-label';
|
||||
|
||||
public function __construct(
|
||||
IRequest $request
|
||||
private IRequest $request,
|
||||
private IPreview $previewManager,
|
||||
) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
|
@ -91,6 +93,7 @@ class Plugin extends ServerPlugin {
|
|||
public function propFind(PropFind $propFind, INode $node): void {
|
||||
if ($node instanceof VersionFile) {
|
||||
$propFind->handle(self::VERSION_LABEL, fn() => $node->getLabel());
|
||||
$propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn () => $this->previewManager->isMimeSupported($node->getContentType()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use OCA\Files_Versions\Versions\INameableVersion;
|
|||
use OCA\Files_Versions\Versions\INameableVersionBackend;
|
||||
use OCA\Files_Versions\Versions\IVersion;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\NotFoundException;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,15 @@
|
|||
:force-display-actions="true"
|
||||
data-files-versions-version>
|
||||
<template #icon>
|
||||
<img v-if="!previewError"
|
||||
<div v-if="!(loadPreview || previewLoaded)" class="version__image" />
|
||||
<img v-else-if="isCurrent || version.hasPreview"
|
||||
:src="previewURL"
|
||||
alt=""
|
||||
decoding="async"
|
||||
fetchpriority="low"
|
||||
loading="lazy"
|
||||
class="version__image"
|
||||
@error="previewError = true">
|
||||
@load="previewLoaded = true">
|
||||
<div v-else
|
||||
class="version__image">
|
||||
<ImageOffOutline :size="20" />
|
||||
|
|
@ -176,13 +180,17 @@ export default {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadPreview: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previewLoaded: false,
|
||||
showVersionLabelForm: false,
|
||||
formVersionLabelValue: this.version.label,
|
||||
capabilities: loadState('core', 'capabilities', { files: { version_labeling: false, version_deletion: false } }),
|
||||
previewError: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||
update(fileInfo) {
|
||||
TabInstance.update(fileInfo)
|
||||
},
|
||||
setIsActive(isActive) {
|
||||
TabInstance.setIsActive(isActive)
|
||||
},
|
||||
destroy() {
|
||||
TabInstance.$destroy()
|
||||
TabInstance = null
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ export default `<?xml version="1.0"?>
|
|||
<d:getcontenttype />
|
||||
<d:getlastmodified />
|
||||
<nc:version-label />
|
||||
<nc:has-preview />
|
||||
</d:prop>
|
||||
</d:propfind>`
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import moment from '@nextcloud/moment'
|
|||
* @property {string} size - Human readable size
|
||||
* @property {string} type - 'file'
|
||||
* @property {number} mtime - Version creation date as a timestamp
|
||||
* @property {boolean} hasPreview - Whether the version has a preview
|
||||
* @property {string} preview - Preview URL of the version
|
||||
* @property {string} url - Download URL of the version
|
||||
* @property {string|null} fileVersion - The version id, null for the current version
|
||||
|
|
@ -98,6 +99,7 @@ function formatVersion(version, fileInfo) {
|
|||
size: version.size,
|
||||
type: version.type,
|
||||
mtime: moment(version.lastmod).unix() * 1000,
|
||||
hasPreview: version.props['has-preview'] === 1,
|
||||
preview: generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', {
|
||||
file: joinPaths(fileInfo.path, fileInfo.name),
|
||||
fileVersion: version.basename,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
<ul data-files-versions-versions-list>
|
||||
<Version v-for="version in orderedVersions"
|
||||
:key="version.mtime"
|
||||
:load-preview="isActive"
|
||||
:version="version"
|
||||
:file-info="fileInfo"
|
||||
:is-current="version.mtime === fileInfo.mtime"
|
||||
|
|
@ -42,6 +43,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
fileInfo: null,
|
||||
isActive: false,
|
||||
/** @type {import('../utils/versions.js').Version[]} */
|
||||
versions: [],
|
||||
loading: false,
|
||||
|
|
@ -89,6 +91,13 @@ export default {
|
|||
this.fetchVersions()
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {boolean} isActive whether the tab is active
|
||||
*/
|
||||
async setIsActive(isActive) {
|
||||
this.isActive = isActive
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the existing versions infos
|
||||
*/
|
||||
|
|
|
|||
4
dist/files-sidebar.js
vendored
4
dist/files-sidebar.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-sidebar.js.map
vendored
2
dist/files-sidebar.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/files_versions-files_versions.js
vendored
4
dist/files_versions-files_versions.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files_versions-files_versions.js.map
vendored
2
dist/files_versions-files_versions.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue