Browse Source

Merge pull request #44417 from nextcloud/fix/files-suffix-folders

fix(files): Only add copy suffix before file extension for files (not folders)
Ferdinand Thiessen 2 months ago
parent
commit
b058af0e5b

+ 9 - 2
apps/files/src/actions/moveOrCopyAction.ts

@@ -120,7 +120,14 @@ export const handleCopyMoveNodeTo = async (node: Node, destination: Folder, meth
 				// If we do not allow overwriting then find an unique name
 				if (!overwrite) {
 					const otherNodes = await client.getDirectoryContents(destinationPath) as FileStat[]
-					target = getUniqueName(node.basename, otherNodes.map((n) => n.basename), copySuffix)
+					target = getUniqueName(
+						node.basename,
+						otherNodes.map((n) => n.basename),
+						{
+							suffix: copySuffix,
+							ignoreFileExtension: node.type === FileType.Folder,
+						},
+					)
 				}
 				await client.copyFile(currentPath, join(destinationPath, target))
 				// If the node is copied into current directory the view needs to be updated
@@ -150,7 +157,7 @@ export const handleCopyMoveNodeTo = async (node: Node, destination: Folder, meth
 						}
 					} catch (error) {
 						// User cancelled
-						showError(t('files','Move cancelled'))
+						showError(t('files', 'Move cancelled'))
 						return
 					}
 				}

+ 21 - 5
apps/files/src/utils/fileUtils.ts

@@ -12,7 +12,7 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU Affero General Public License for more details.
  *
  * You should have received a copy of the GNU Affero General Public License
@@ -28,15 +28,31 @@ import { translate as t, translatePlural as n } from '@nextcloud/l10n'
  * Create an unique file name
  * @param name The initial name to use
  * @param otherNames Other names that are already used
- * @param suffix A function that takes an index an returns a suffix to add, defaults to '(index)'
+ * @param options Optional parameters for tuning the behavior
+ * @param options.suffix A function that takes an index and returns a suffix to add to the file name, defaults to '(index)'
+ * @param options.ignoreFileExtension Set to true to ignore the file extension when adding the suffix (when getting a unique directory name)
  * @return Either the initial name, if unique, or the name with the suffix so that the name is unique
  */
-export const getUniqueName = (name: string, otherNames: string[], suffix = (n: number) => `(${n})`): string => {
+export const getUniqueName = (
+	name: string,
+	otherNames: string[],
+	options: {
+		suffix?: (i: number) => string,
+		ignoreFileExtension?: boolean,
+	} = {},
+): string => {
+	const opts = {
+		suffix: (n: number) => `(${n})`,
+		ignoreFileExtension: false,
+		...options,
+	}
+
 	let newName = name
 	let i = 1
 	while (otherNames.includes(newName)) {
-		const ext = extname(name)
-		newName = `${basename(name, ext)} ${suffix(i++)}${ext}`
+		const ext = opts.ignoreFileExtension ? '' : extname(name)
+		const base = basename(name, ext)
+		newName = `${base} ${opts.suffix(i++)}${ext}`
 	}
 	return newName
 }

+ 19 - 2
cypress/e2e/files/files_copy-move.cy.ts

@@ -72,7 +72,9 @@ describe('Files: Move or copy files', { testIsolation: true }, () => {
 		getRowForFile('new-folder').should('not.exist')
 	})
 
-	// This was a bug previously
+	/**
+	 * Test for https://github.com/nextcloud/server/issues/41768
+	 */
 	it('Can move a file to folder with similar name', () => {
 		cy.uploadContent(currentUser, new Blob(), 'text/plain', '/original')
 			.mkdir(currentUser, '/original folder')
@@ -138,8 +140,23 @@ describe('Files: Move or copy files', { testIsolation: true }, () => {
 		getRowForFile('original (copy 2).txt').should('be.visible')
 	})
 
+	/**
+	 * Test that a copied folder with a dot will be renamed correctly ('foo.bar' -> 'foo.bar (copy)')
+	 * Test for: https://github.com/nextcloud/server/issues/43843
+	 */
+	it('Can copy a folder to same folder', () => {
+		cy.mkdir(currentUser, '/foo.bar')
+		cy.login(currentUser)
+		cy.visit('/apps/files')
+
+		copyFile('foo.bar', '.')
+
+		getRowForFile('foo.bar').should('be.visible')
+		getRowForFile('foo.bar (copy)').should('be.visible')
+	})
+
 	/** Test for https://github.com/nextcloud/server/issues/43329 */
-	context.only('escaping file and folder names', () => {
+	context('escaping file and folder names', () => {
 		it('Can handle files with special characters', () => {
 			cy.uploadContent(currentUser, new Blob(), 'text/plain', '/original.txt')
 				.mkdir(currentUser, '/can\'t say')

File diff suppressed because it is too large
+ 0 - 0
dist/files-init.js


File diff suppressed because it is too large
+ 0 - 0
dist/files-init.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/files-main.js


File diff suppressed because it is too large
+ 0 - 0
dist/files-main.js.map


Some files were not shown because too many files changed in this diff