From 41e78efeadf43c73939d6417d0a8e4b0c27820d2 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 9 Jul 2026 17:36:54 +0200 Subject: [PATCH] fix(files_versions): properly mark current version Signed-off-by: Ferdinand Thiessen --- apps/files_versions/lib/Sabre/Plugin.php | 5 +++++ apps/files_versions/src/utils/davRequest.ts | 1 + apps/files_versions/src/utils/versions.ts | 5 ++++- apps/files_versions/src/views/FilesVersionsSidebarTab.vue | 6 ++---- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/files_versions/lib/Sabre/Plugin.php b/apps/files_versions/lib/Sabre/Plugin.php index a26a9c874558b..cb7793ec2c665 100644 --- a/apps/files_versions/lib/Sabre/Plugin.php +++ b/apps/files_versions/lib/Sabre/Plugin.php @@ -33,6 +33,7 @@ class Plugin extends ServerPlugin { public const AUTHOR = 'author'; public const VERSION_LABEL = '{http://nextcloud.org/ns}version-label'; public const VERSION_AUTHOR = '{http://nextcloud.org/ns}version-author'; + public const VERSION_IS_CURRENT = '{http://nextcloud.org/ns}version-is-current'; private const LEGACY_FILENAME_HEADER_USER_AGENTS = [ // Quirky clients Request::USER_AGENT_IE, Request::USER_AGENT_ANDROID_MOBILE_CHROME, @@ -101,6 +102,10 @@ public function propFind(PropFind $propFind, INode $node): void { self::VERSION_AUTHOR, fn () => $node->getMetadataValue(self::AUTHOR) ); + $propFind->handle( + self::VERSION_IS_CURRENT, + fn (): string => $node->getVersion()->getTimestamp() === $node->getVersion()->getSourceFile()->getMTime() ? 'true' : 'false' + ); $propFind->handle( FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn (): string => $this->previewManager->isMimeSupported($node->getContentType()) ? 'true' : 'false', diff --git a/apps/files_versions/src/utils/davRequest.ts b/apps/files_versions/src/utils/davRequest.ts index 1dcf620564a7a..b1ce7972338d6 100644 --- a/apps/files_versions/src/utils/davRequest.ts +++ b/apps/files_versions/src/utils/davRequest.ts @@ -15,6 +15,7 @@ export default ` + ` diff --git a/apps/files_versions/src/utils/versions.ts b/apps/files_versions/src/utils/versions.ts index 47943b1590102..5ebb6173e4f9f 100644 --- a/apps/files_versions/src/utils/versions.ts +++ b/apps/files_versions/src/utils/versions.ts @@ -20,6 +20,7 @@ export interface Version { label: string // 'Current version' or '' author: string | null // UID for the author of the version authorName: string | null // Display name of the author + isCurrent: boolean // True if this is the current version filename: string // File name relative to the version DAV endpoint basename: string // A base name generated from the mtime mime: string // Empty for the current version, else the actual mime type of the version @@ -98,9 +99,10 @@ export async function restoreVersion(version: Version) { */ function formatVersion(version: Required, node: INode): Version { const mtime = Date.parse(version.lastmod) + const isCurrentVersion = version.props['version-is-current'] === 'true' || mtime === node.mtime?.getTime() let previewUrl: string - if (mtime === node.mtime?.getTime()) { // Version is the current one + if (isCurrentVersion) { previewUrl = generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0&forceIcon=1&mimeFallback=1', { fileId: node.id, fileEtag: node.attributes.etag, @@ -118,6 +120,7 @@ function formatVersion(version: Required, node: INode): Version { label: version.props['version-label'] ? String(version.props['version-label']) : '', author: version.props['version-author'] ? String(version.props['version-author']) : null, authorName: null, + isCurrent: isCurrentVersion, filename: version.filename, basename: new Date(mtime).toLocaleString( [getCanonicalLocale(), getCanonicalLocale().split('-')[0]!], diff --git a/apps/files_versions/src/views/FilesVersionsSidebarTab.vue b/apps/files_versions/src/views/FilesVersionsSidebarTab.vue index b35fe6118773b..4acbc29938fff 100644 --- a/apps/files_versions/src/views/FilesVersionsSidebarTab.vue +++ b/apps/files_versions/src/views/FilesVersionsSidebarTab.vue @@ -18,7 +18,7 @@ :loadPreview="active" :version="row.items[0].version" :node="node" - :isCurrent="row.items[0].version.mtime === currentVersionMtime" + :isCurrent="row.items[0].version.isCurrent" :isFirstVersion="row.items[0].version.mtime === initialVersionMtime" @click="openVersion" @compare="compareVersion" @@ -73,8 +73,6 @@ const loading = ref(false) const showVersionLabelForm = ref(false) const editedVersion = ref(null) -const currentVersionMtime = computed(() => props.node?.mtime?.getTime() ?? 0) - /** * Order versions by mtime. * Put the current version at the top. @@ -131,7 +129,7 @@ const canCompare = computed(() => { // When the id changed we immediately show changes watch(() => props.node.id, loadVersions, { immediate: true }) // On mtime changes we debounce to prevent too many requests. -watchDebounced(currentVersionMtime, loadVersions, { debounce: 600 }) +watchDebounced(() => props.node.mtime?.getTime(), loadVersions, { debounce: 600 }) /** * Load versions for the current node