From 171ffb8a2cb3f8cd1c0fd1275f9069d6f15d77c2 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Tue, 19 May 2026 15:36:14 +0200 Subject: [PATCH] fix(files): use displayname rather than basename to use progress - resolves https://github.com/nextcloud/end_to_end_encryption/issues/1733 The internal basename is often not known by users, e.g. groupfolders or in this case e2ee can define displaynames other than the shown name. Same for e.g. mount points of shares. So we need to show the displayname instead. Signed-off-by: Ferdinand Thiessen --- apps/files/src/actions/moveOrCopyAction.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/files/src/actions/moveOrCopyAction.ts b/apps/files/src/actions/moveOrCopyAction.ts index 68f00f48ce2..6912928c99c 100644 --- a/apps/files/src/actions/moveOrCopyAction.ts +++ b/apps/files/src/actions/moveOrCopyAction.ts @@ -14,9 +14,9 @@ import { FilePickerClosed, getFilePickerBuilder, openConflictPicker, showError, import { emit } from '@nextcloud/event-bus' import { FileType, getUniqueName, NodeStatus, Permission } from '@nextcloud/files' import { defaultRootPath, getClient, getDefaultPropfind, resultToNode } from '@nextcloud/files/dav' -import { t } from '@nextcloud/l10n' +import { n, t } from '@nextcloud/l10n' +import { basename, join } from '@nextcloud/paths' import { getConflicts } from '@nextcloud/upload' -import { basename, join } from 'path' import Vue from 'vue' import { getContents } from '../services/Files.ts' import { logger } from '../utils/logger.ts' @@ -156,7 +156,11 @@ export async function* handleCopyMoveNodesTo(nodes: INode[], destination: IFolde } } - const actionFinished = createLoadingNotification(method, nodes.map((node) => node.basename), destination.path) + const actionFinished = createLoadingNotification( + method, + nodes.map((node) => node.displayname), + join(destination.dirname, destination.displayname), + ) const queue = getQueue() try { for (const node of nodes) { @@ -246,11 +250,11 @@ function createLoadingNotification(mode: MoveCopyAction, sources: string[], dest const text = mode === MoveCopyAction.MOVE ? (sources.length === 1 ? t('files', 'Moving "{source}" to "{destination}" …', { source: sources[0]!, destination }) - : t('files', 'Moving {count} files to "{destination}" …', { count: sources.length, destination }) + : n('files', 'Moving %n file to "{destination}" …', 'Moving %n files to "{destination}" …', sources.length, { destination }) ) : (sources.length === 1 ? t('files', 'Copying "{source}" to "{destination}" …', { source: sources[0]!, destination }) - : t('files', 'Copying {count} files to "{destination}" …', { count: sources.length, destination }) + : n('files', 'Copying %n file to "{destination}" …', 'Copying %n files to "{destination}" …', sources.length, { destination }) ) const toast = showLoading(text) @@ -324,7 +328,7 @@ async function openFilePickerForAction( if (action === MoveCopyAction.MOVE || action === MoveCopyAction.MOVE_OR_COPY) { buttons.push({ - label: target ? t('files', 'Move to {target}', { target }, undefined, { escape: false, sanitize: false }) : t('files', 'Move'), + label: target ? t('files', 'Move to {target}', { target }, { escape: false, sanitize: false }) : t('files', 'Move'), variant: action === MoveCopyAction.MOVE ? 'primary' : 'secondary', icon: FolderMoveSvg, async callback(destination) {