@@ -10,16 +10,25 @@ import { faLevelUpAlt } from '@fortawesome/free-solid-svg-icons/faLevelUpAlt';
1010import RenameFileModal from '@/components/server/files/RenameFileModal' ;
1111import { ServerContext } from '@/state/server' ;
1212import CopyFileModal from '@/components/server/files/CopyFileModal' ;
13+ import { join } from 'path' ;
14+ import deleteFile from '@/api/server/files/deleteFile' ;
15+ import SpinnerOverlay from '@/components/elements/SpinnerOverlay' ;
16+ import copyFile from '@/api/server/files/copyFile' ;
17+ import { httpErrorToHuman } from '@/api/http' ;
1318
14- type ModalType = 'rename' | 'move' | 'copy' | 'download' | 'delete' ;
19+ type ModalType = 'rename' | 'move' ;
1520
1621export default ( { uuid } : { uuid : string } ) => {
1722 const menu = createRef < HTMLDivElement > ( ) ;
1823 const [ visible , setVisible ] = useState ( false ) ;
24+ const [ showSpinner , setShowSpinner ] = useState ( false ) ;
1925 const [ modal , setModal ] = useState < ModalType | null > ( null ) ;
2026 const [ posX , setPosX ] = useState ( 0 ) ;
2127
28+ const server = ServerContext . useStoreState ( state => state . server . data ! ) ;
2229 const file = ServerContext . useStoreState ( state => state . files . contents . find ( file => file . uuid === uuid ) ) ;
30+ const directory = ServerContext . useStoreState ( state => state . files . directory ) ;
31+ const { removeFile, getDirectoryContents } = ServerContext . useStoreActions ( actions => actions . files ) ;
2332 if ( ! file ) {
2433 return null ;
2534 }
@@ -38,6 +47,27 @@ export default ({ uuid }: { uuid: string }) => {
3847 }
3948 } ;
4049
50+ const doDeletion = ( ) => {
51+ setShowSpinner ( true ) ;
52+ deleteFile ( server . uuid , join ( directory , file . name ) )
53+ . then ( ( ) => removeFile ( uuid ) )
54+ . catch ( error => {
55+ console . error ( 'Error while attempting to delete a file.' , error ) ;
56+ setShowSpinner ( false ) ;
57+ } ) ;
58+ } ;
59+
60+ const doCopy = ( ) => {
61+ setShowSpinner ( true ) ;
62+ copyFile ( server . uuid , join ( directory , file . name ) )
63+ . then ( ( ) => getDirectoryContents ( directory ) )
64+ . catch ( error => {
65+ console . error ( 'Error while attempting to copy file.' , error ) ;
66+ alert ( httpErrorToHuman ( error ) ) ;
67+ setShowSpinner ( false ) ;
68+ } ) ;
69+ } ;
70+
4171 useEffect ( ( ) => {
4272 visible
4373 ? document . addEventListener ( 'click' , windowListener )
@@ -69,13 +99,13 @@ export default ({ uuid }: { uuid: string }) => {
6999 } }
70100 >
71101 < FontAwesomeIcon icon = { faEllipsisH } />
102+ { visible &&
103+ < React . Fragment >
104+ < RenameFileModal file = { file } visible = { modal === 'rename' } onDismissed = { ( ) => setModal ( null ) } />
105+ < SpinnerOverlay visible = { showSpinner } fixed = { true } large = { true } />
106+ </ React . Fragment >
107+ }
72108 </ div >
73- { visible &&
74- < React . Fragment >
75- < RenameFileModal file = { file } visible = { modal === 'rename' } onDismissed = { ( ) => setModal ( null ) } />
76- { modal === 'copy' && < CopyFileModal file = { file } onCopyComplete = { ( ) => setModal ( null ) } /> }
77- </ React . Fragment >
78- }
79109 < CSSTransition timeout = { 250 } in = { visible } unmountOnExit = { true } classNames = { 'fade' } >
80110 < div
81111 className = { 'absolute bg-white p-2 rounded border border-neutral-700 shadow-lg text-neutral-500 min-w-48' }
@@ -93,7 +123,7 @@ export default ({ uuid }: { uuid: string }) => {
93123 < span className = { 'ml-2' } > Move</ span >
94124 </ div >
95125 < div
96- onClick = { ( ) => setModal ( 'copy' ) }
126+ onClick = { ( ) => doCopy ( ) }
97127 className = { 'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded' }
98128 >
99129 < FontAwesomeIcon icon = { faCopy } className = { 'text-xs' } />
@@ -103,7 +133,10 @@ export default ({ uuid }: { uuid: string }) => {
103133 < FontAwesomeIcon icon = { faFileDownload } className = { 'text-xs' } />
104134 < span className = { 'ml-2' } > Download</ span >
105135 </ div >
106- < div className = { 'hover:text-red-700 p-2 flex items-center hover:bg-red-100 rounded' } >
136+ < div
137+ onClick = { ( ) => doDeletion ( ) }
138+ className = { 'hover:text-red-700 p-2 flex items-center hover:bg-red-100 rounded' }
139+ >
107140 < FontAwesomeIcon icon = { faTrashAlt } className = { 'text-xs' } />
108141 < span className = { 'ml-2' } > Delete</ span >
109142 </ div >
0 commit comments