@@ -8,7 +8,7 @@ import type { FileStat, ResponseDataDetailed } from 'webdav'
88import type { MoveCopyResult } from './moveOrCopyActionUtils'
99
1010import { isAxiosError } from '@nextcloud/axios'
11- import { FilePickerClosed , getFilePickerBuilder , showError , showInfo } from '@nextcloud/dialogs'
11+ import { FilePickerClosed , getFilePickerBuilder , showError , showInfo , TOAST_PERMANENT_TIMEOUT } from '@nextcloud/dialogs'
1212import { emit } from '@nextcloud/event-bus'
1313import { FileAction , FileType , NodeStatus , davGetClient , davRootPath , davResultToNode , davGetDefaultPropfind , getUniqueName , Permission } from '@nextcloud/files'
1414import { translate as t } from '@nextcloud/l10n'
@@ -40,6 +40,28 @@ const getActionForNodes = (nodes: Node[]): MoveCopyAction => {
4040 return MoveCopyAction . COPY
4141}
4242
43+ /**
44+ * Create a loading notification toast
45+ * @param mode The move or copy mode
46+ * @param source Name of the node that is copied / moved
47+ * @param destination Destination path
48+ * @return {() => void } Function to hide the notification
49+ */
50+ function createLoadingNotification ( mode : MoveCopyAction , source : string , destination : string ) : ( ) => void {
51+ const text = mode === MoveCopyAction . MOVE ? t ( 'files' , 'Moving "{source}" to "{destination}" …' , { source, destination } ) : t ( 'files' , 'Copying "{source}" to "{destination}" …' , { source, destination } )
52+
53+ let toast : ReturnType < typeof showInfo > | undefined
54+ toast = showInfo (
55+ `<span class="icon icon-loading-small toast-loading-icon"></span> ${ text } ` ,
56+ {
57+ isHTML : true ,
58+ timeout : TOAST_PERMANENT_TIMEOUT ,
59+ onRemove : ( ) => { toast ?. hideToast ( ) ; toast = undefined } ,
60+ } ,
61+ )
62+ return ( ) => toast && toast . hideToast ( )
63+ }
64+
4365/**
4466 * Handle the copy/move of a node to a destination
4567 * This can be imported and used by other scripts/components on server
@@ -80,6 +102,7 @@ export const handleCopyMoveNodeTo = async (node: Node, destination: Folder, meth
80102
81103 // Set loading state
82104 Vue . set ( node , 'status' , NodeStatus . LOADING )
105+ const actionFinished = createLoadingNotification ( method , node . basename , destination . path )
83106
84107 const queue = getQueue ( )
85108 return await queue . add ( async ( ) => {
@@ -162,7 +185,8 @@ export const handleCopyMoveNodeTo = async (node: Node, destination: Folder, meth
162185 logger . debug ( error as Error )
163186 throw new Error ( )
164187 } finally {
165- Vue . set ( node , 'status' , undefined )
188+ Vue . set ( node , 'status' , '' )
189+ actionFinished ( )
166190 }
167191 } )
168192}
@@ -309,7 +333,7 @@ export const action = new FileAction({
309333 if ( result === false ) {
310334 showInfo ( nodes . length === 1
311335 ? t ( 'files' , 'Cancelled move or copy of "{filename}".' , { filename : nodes [ 0 ] . displayname } )
312- : t ( 'files' , 'Cancelled move or copy operation' )
336+ : t ( 'files' , 'Cancelled move or copy operation' ) ,
313337 )
314338 return nodes . map ( ( ) => null )
315339 }
0 commit comments