diff options
author | skjnldsv <skjnldsv@protonmail.com> | 2024-12-12 12:55:04 +0100 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2024-12-12 10:08:38 -0800 |
commit | e8b0bdc5f4e46ade1996d22d67abbf5c48672f24 (patch) | |
tree | bfd8b92e69946003397616ec4ea7b23685c206a2 /apps | |
parent | 46573b75a6ca3157b0eaa1b4e2ee0624697b723d (diff) | |
download | nextcloud-server-e8b0bdc5f4e46ade1996d22d67abbf5c48672f24.tar.gz nextcloud-server-e8b0bdc5f4e46ade1996d22d67abbf5c48672f24.zip |
perf(files_trashbin): use empty trashbin endpoint instead of batch delete requests
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files_trashbin/src/fileListActions/emptyTrashAction.ts | 110 |
1 files changed, 41 insertions, 69 deletions
diff --git a/apps/files_trashbin/src/fileListActions/emptyTrashAction.ts b/apps/files_trashbin/src/fileListActions/emptyTrashAction.ts index 9c45d6a8565..bba0264cd93 100644 --- a/apps/files_trashbin/src/fileListActions/emptyTrashAction.ts +++ b/apps/files_trashbin/src/fileListActions/emptyTrashAction.ts @@ -4,7 +4,7 @@ */ import type { Node, View, Folder } from '@nextcloud/files' -import PQueue from 'p-queue' +import axios from '@nextcloud/axios' import { FileListAction } from '@nextcloud/files' import { t } from '@nextcloud/l10n' import { @@ -13,57 +13,23 @@ import { showError, showInfo, showSuccess, - TOAST_PERMANENT_TIMEOUT, } from '@nextcloud/dialogs' -import { deleteNode } from '../../../files/src/actions/deleteUtils.ts' import { logger } from '../logger.ts' +import { generateRemoteUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' +import { emit } from '@nextcloud/event-bus' -type Toast = ReturnType<typeof showInfo> - -const queue = new PQueue({ concurrency: 5 }) - -const showLoadingToast = (): null | Toast => { - const message = t('files_trashbin', 'Deleting files…') - let toast: null | Toast = null - toast = showInfo( - `<span class="icon icon-loading-small toast-loading-icon"></span> ${message}`, - { - isHTML: true, - timeout: TOAST_PERMANENT_TIMEOUT, - onRemove: () => { - toast?.hideToast() - toast = null - }, - }, - ) - return toast -} - -const emptyTrash = async (nodes: Node[]) => { - const promises = nodes.map((node) => { - const { promise, resolve, reject } = Promise.withResolvers<void>() - queue.add(async () => { - try { - await deleteNode(node) - resolve() - } catch (error) { - logger.error('Failed to delete node', { error, node }) - reject(error) - } - }) - return promise - }) - - const toast = showLoadingToast() - const results = await Promise.allSettled(promises) - if (results.some((result) => result.status === 'rejected')) { - toast?.hideToast() +const emptyTrash = async (): Promise<boolean> => { + try { + await axios.delete(generateRemoteUrl('dav') + `/trashbin/${getCurrentUser()?.uid}/trash`) + showSuccess(t('files_trashbin', 'Permanently deleted all previously deleted files')) + return true + } catch (error) { showError(t('files_trashbin', 'Failed to delete all previously deleted files')) - return + logger.error('Failed to delete all previously deleted files', { error }) + return false } - toast?.hideToast() - showSuccess(t('files_trashbin', 'Permanently deleted all previously deleted files')) } export const emptyTrashAction = new FileListAction({ @@ -79,31 +45,37 @@ export const emptyTrashAction = new FileListAction({ return nodes.length > 0 && folder.path === '/' }, - async exec(view: View, nodes: Node[]) { - const dialog = getDialogBuilder(t('files_trashbin', 'Confirm permanent deletion')) - .setSeverity(DialogSeverity.Warning) - // TODO Add note for groupfolders - .setText(t('files_trashbin', 'Are you sure you want to permanently delete all previously deleted files? This cannot be undone.')) - .setButtons([ - { - label: t('files_trashbin', 'Cancel'), - type: 'secondary', - callback: () => {}, - }, - { - label: t('files_trashbin', 'Empty deleted files'), - type: 'error', - callback: () => { - emptyTrash(nodes) + async exec(view: View, nodes: Node[]): Promise<void> { + const askConfirmation = new Promise((resolve) => { + const dialog = getDialogBuilder(t('files_trashbin', 'Confirm permanent deletion')) + .setSeverity(DialogSeverity.Warning) + // TODO Add note for groupfolders + .setText(t('files_trashbin', 'Are you sure you want to permanently delete all previously deleted files? This cannot be undone.')) + .setButtons([ + { + label: t('files_trashbin', 'Cancel'), + type: 'secondary', + callback: () => resolve(false), + }, + { + label: t('files_trashbin', 'Empty deleted files'), + type: 'error', + callback: () => resolve(true), }, - }, - ]) - .build() + ]) + .build() + dialog.show().then(() => { + dialog.hide() + }) + }) - try { - await dialog.show() - } catch (error) { - // Allow throw on dialog close + const result = await askConfirmation + if (result === true) { + await emptyTrash() + nodes.forEach((node) => emit('files:node:deleted', node)) + return } + + showInfo(t('files_trashbin', 'Deletion cancelled')) }, }) |