@@ -121,6 +121,11 @@ const runDcm2niix = async (files) => {
121121 console . log ( resultFileList ) ;
122122 hideLoadingCircle ( )
123123 showFileSelect ( )
124+ // set the first file as the selected file
125+ fileSelect . value = 0
126+ // trigger the change event
127+ const event = new Event ( 'change' )
128+ fileSelect . dispatchEvent ( event )
124129 } catch ( error ) {
125130 console . error ( error ) ;
126131 resultFileList = [ ]
@@ -139,6 +144,72 @@ const ensureObjectOfObjects = (obj) => {
139144 }
140145}
141146
147+ async function handleDrop ( e ) {
148+ e . preventDefault ( ) ; // prevent navigation to open file
149+ const items = e . dataTransfer . items ;
150+ try {
151+ showLoadingCircle ( )
152+ const files = [ ] ;
153+ for ( let i = 0 ; i < items . length ; i ++ ) {
154+ const item = items [ i ] . webkitGetAsEntry ( ) ;
155+ if ( item ) {
156+ await traverseFileTree ( item , '' , files ) ;
157+ }
158+ }
159+ const dcm2niix = new Dcm2niix ( ) ;
160+ await dcm2niix . init ( )
161+ resultFileList = await dcm2niix . inputFromDropItems ( files ) . run ( )
162+ resultFileList = resultFileList . filter ( file => file . name . endsWith ( '.nii' ) )
163+ updateSelectItems ( resultFileList )
164+ console . log ( resultFileList ) ;
165+ hideLoadingCircle ( )
166+ showFileSelect ( )
167+ // set the first file as the selected file
168+ fileSelect . value = 0
169+ // trigger the change event
170+ const event = new Event ( 'change' )
171+ fileSelect . dispatchEvent ( event )
172+ showText ( '' )
173+ } catch ( error ) {
174+ console . error ( error ) ;
175+ hideLoadingCircle ( )
176+ hideFileSelect ( )
177+ showText ( 'Error converting files. Check the console for more information.' )
178+ }
179+ }
180+
181+ async function traverseFileTree ( item , path = '' , fileArray ) {
182+ return new Promise ( ( resolve ) => {
183+ if ( item . isFile ) {
184+ item . file ( file => {
185+ file . fullPath = path + file . name ;
186+ // IMPORTANT: _webkitRelativePath is required for dcm2niix to work.
187+ // We need to add this property so we can parse multiple directories correctly.
188+ // the "webkitRelativePath" property on File objects is read-only, so we can't set it directly, hence the underscore.
189+ file . _webkitRelativePath = path + file . name ;
190+ fileArray . push ( file ) ;
191+ resolve ( ) ;
192+ } ) ;
193+ } else if ( item . isDirectory ) {
194+ const dirReader = item . createReader ( ) ;
195+ const readAllEntries = ( ) => {
196+ dirReader . readEntries ( entries => {
197+ if ( entries . length > 0 ) {
198+ const promises = [ ] ;
199+ for ( const entry of entries ) {
200+ promises . push ( traverseFileTree ( entry , path + item . name + '/' , fileArray ) ) ;
201+ }
202+ Promise . all ( promises ) . then ( readAllEntries ) ;
203+ } else {
204+ resolve ( ) ;
205+ }
206+ } ) ;
207+ } ;
208+ readAllEntries ( ) ;
209+ }
210+ } ) ;
211+ }
212+
142213async function main ( ) {
143214 fileInput . addEventListener ( 'change' , async ( event ) => {
144215 if ( event . target . files . length === 0 ) {
@@ -147,13 +218,17 @@ async function main() {
147218 }
148219 console . log ( 'Selected files:' , event . target . files ) ;
149220 const selectedFiles = event . target . files ;
150- const files = ensureObjectOfObjects ( selectedFiles )
221+ const files = ensureObjectOfObjects ( selectedFiles ) // probably not needed anymore with new dcm2niix version
151222 await runDcm2niix ( files )
152223 } ) ;
153224
154225 // when user changes the file to view
155226 fileSelect . onchange = handleFileSelectChange
156227
228+ // handle drag and drop
229+ dropTarget . ondrop = handleDrop ;
230+ dropTarget . ondragover = ( e ) => { e . preventDefault ( ) ; }
231+
157232 // when user clicks save
158233 saveButton . onclick = handleSaveButtonClick
159234
0 commit comments