Merge pull request #46963 from nextcloud/fix/move-copy-error

pull/46958/head
John Molakvoæ 2024-08-02 02:20:45 +07:00 committed by GitHub
commit aabd6ef8be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 38 additions and 19 deletions

@ -8,7 +8,7 @@ import type { FileStat, ResponseDataDetailed } from 'webdav'
import type { MoveCopyResult } from './moveOrCopyActionUtils'
import { isAxiosError } from '@nextcloud/axios'
import { FilePickerClosed, getFilePickerBuilder, showError } from '@nextcloud/dialogs'
import { FilePickerClosed, getFilePickerBuilder, showError, showInfo } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
import { FileAction, FileType, NodeStatus, davGetClient, davRootPath, davResultToNode, davGetDefaultPropfind, getUniqueName, Permission } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
@ -167,12 +167,17 @@ export const handleCopyMoveNodeTo = async (node: Node, destination: Folder, meth
/**
* Open a file picker for the given action
* @param {MoveCopyAction} action The action to open the file picker for
* @param {string} dir The directory to start the file picker in
* @param {Node[]} nodes The nodes to move/copy
* @return {Promise<MoveCopyResult>} The picked destination
* @param action The action to open the file picker for
* @param dir The directory to start the file picker in
* @param nodes The nodes to move/copy
* @return The picked destination or false if cancelled by user
*/
const openFilePickerForAction = async (action: MoveCopyAction, dir = '/', nodes: Node[]): Promise<MoveCopyResult> => {
async function openFilePickerForAction(
action: MoveCopyAction,
dir = '/',
nodes: Node[],
): Promise<MoveCopyResult | false> {
const { resolve, reject, promise } = Promise.withResolvers<MoveCopyResult | false>()
const fileIDs = nodes.map(node => node.fileid).filter(Boolean)
const filePicker = getFilePickerBuilder(t('files', 'Choose destination'))
.allowDirectories(true)
@ -183,9 +188,7 @@ const openFilePickerForAction = async (action: MoveCopyAction, dir = '/', nodes:
.setMimeTypeFilter([])
.setMultiSelect(false)
.startAt(dir)
return new Promise((resolve, reject) => {
filePicker.setButtonFactory((selection: Node[], path: string) => {
.setButtonFactory((selection: Node[], path: string) => {
const buttons: IFilePickerButton[] = []
const target = basename(path)
@ -234,17 +237,19 @@ const openFilePickerForAction = async (action: MoveCopyAction, dir = '/', nodes:
return buttons
})
.build()
const picker = filePicker.build()
picker.pick().catch((error) => {
filePicker.pick()
.catch((error: Error) => {
logger.debug(error as Error)
if (error instanceof FilePickerClosed) {
reject(new Error(t('files', 'Cancelled move or copy operation')))
resolve(false)
} else {
reject(new Error(t('files', 'Move or copy operation failed')))
}
})
})
return promise
}
export const action = new FileAction({
@ -277,6 +282,11 @@ export const action = new FileAction({
logger.error(e as Error)
return false
}
if (result === false) {
showInfo(t('files', 'Cancelled move or copy of "{filename}".', { filename: node.displayname }))
return null
}
try {
await handleCopyMoveNodeTo(node, result.destination, result.action)
return true
@ -293,6 +303,15 @@ export const action = new FileAction({
async execBatch(nodes: Node[], view: View, dir: string) {
const action = getActionForNodes(nodes)
const result = await openFilePickerForAction(action, dir, nodes)
// Handle cancellation silently
if (result === false) {
showInfo(nodes.length === 1
? t('files', 'Cancelled move or copy of "{filename}".', { filename: nodes[0].displayname })
: t('files', 'Cancelled move or copy operation')
)
return nodes.map(() => null)
}
const promises = nodes.map(async node => {
try {
await handleCopyMoveNodeTo(node, result.destination, result.action)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long