@@ -95,32 +95,41 @@ export default class Settings {
9595 children : [
9696 {
9797 tag : 'div' ,
98- class : 'fs_icons ' ,
98+ class : 'menu_icons ' ,
9999 children : [
100100 {
101101 tag : 'div' ,
102- class : 'icon moon' ,
103- title : 'Dark mode' ,
104- events : {
105- click : ( ) => {
106- document . body . classList . toggle ( 'theme_dark' ) ;
107- localStorage . setItem ( 'dark' , document . body . classList . contains ( 'theme_dark' ) | 0 ) ;
108- } ,
102+ class : 'menu_icon' ,
103+ child : {
104+ tag : 'div' ,
105+ class : 'icon moon' ,
106+ title : 'Dark mode' ,
107+ events : {
108+ click : ( ) => {
109+ document . body . classList . toggle ( 'theme_dark' ) ;
110+ localStorage . setItem ( 'dark' , document . body . classList . contains ( 'theme_dark' ) | 0 ) ;
111+ } ,
112+ }
109113 }
110114 } ,
111115 {
116+
112117 tag : 'div' ,
113- class : 'icon key' ,
114- title : 'Auth' ,
115- var : 'auth' ,
116- events : {
117- click : async ( ) => {
118- let res = await AsyncPrompt ( 'Password' , '' ) ;
119- if ( res !== null ) {
120- localStorage . setItem ( 'auth' , hash ( res ) ) ;
121- window . location . reload ( ) ;
122- }
123- } ,
118+ class : 'menu_icon' ,
119+ child : {
120+ tag : 'div' ,
121+ class : 'icon key' ,
122+ title : 'Auth' ,
123+ var : 'auth' ,
124+ events : {
125+ click : async ( ) => {
126+ let res = await AsyncPrompt ( 'Password' , '' ) ;
127+ if ( res !== null ) {
128+ localStorage . setItem ( 'auth' , hash ( res ) ) ;
129+ window . location . reload ( ) ;
130+ }
131+ } ,
132+ }
124133 }
125134 } ,
126135 {
@@ -130,16 +139,23 @@ export default class Settings {
130139 style : 'display: none' ,
131140 accept : '.bin' ,
132141 events : {
133- change : ( ) => this . uploadOta ( ) ,
142+ change : ( ) => this . uploadOta ( this . $upload_ota . files [ 0 ] ) ,
134143 }
135144 } ,
136145 {
137146 tag : 'div' ,
138- class : 'icon cloud' ,
139- title : 'OTA' ,
140- var : 'ota' ,
147+ class : 'menu_icon drop_area' ,
141148 events : {
142- click : ( ) => this . $upload_ota . click ( ) ,
149+ drop : ( e ) => this . uploadOta ( e . dataTransfer . files [ 0 ] ) ,
150+ } ,
151+ child : {
152+ tag : 'div' ,
153+ class : 'icon cloud' ,
154+ title : 'OTA' ,
155+ var : 'ota' ,
156+ events : {
157+ click : ( ) => this . $upload_ota . click ( ) ,
158+ }
143159 }
144160 } ,
145161 {
@@ -148,16 +164,23 @@ export default class Settings {
148164 var : 'upload_file' ,
149165 style : 'display: none' ,
150166 events : {
151- change : ( ) => this . uploadFile ( ) ,
167+ change : ( ) => this . uploadFile ( this . $upload_file . files [ 0 ] ) ,
152168 }
153169 } ,
154170 {
155171 tag : 'div' ,
156- class : 'icon upload' ,
157- title : 'Upload' ,
158- var : 'upload' ,
172+ class : 'menu_icon drop_area' ,
159173 events : {
160- click : ( ) => this . $upload_file . click ( ) ,
174+ drop : ( e ) => this . uploadFile ( e . dataTransfer . files [ 0 ] ) ,
175+ } ,
176+ child : {
177+ tag : 'div' ,
178+ class : 'icon upload' ,
179+ title : 'Upload' ,
180+ var : 'upload' ,
181+ events : {
182+ click : ( ) => this . $upload_file . click ( ) ,
183+ }
161184 }
162185 } ,
163186 ]
@@ -214,6 +237,23 @@ export default class Settings {
214237 this . back ( ) ;
215238 }
216239
240+ [ 'dragenter' , 'dragover' , 'dragleave' , 'drop' ] . forEach ( ev => {
241+ document . body . addEventListener ( ev , ( e ) => {
242+ e . preventDefault ( ) ;
243+ e . stopPropagation ( ) ;
244+ } , false ) ;
245+ } ) ;
246+ [ 'dragenter' , 'dragover' ] . forEach ( e => {
247+ document . body . addEventListener ( e , function ( ) {
248+ document . querySelectorAll ( '.drop_area' ) . forEach ( ( el ) => el . classList . add ( 'active' ) ) ;
249+ } , false ) ;
250+ } ) ;
251+ [ 'dragleave' , 'drop' ] . forEach ( e => {
252+ document . body . addEventListener ( e , function ( ) {
253+ document . querySelectorAll ( '.drop_area' ) . forEach ( ( el ) => el . classList . remove ( 'active' ) ) ;
254+ } , false ) ;
255+ } ) ;
256+
217257 if ( localStorage . hasOwnProperty ( 'dark' ) ) {
218258 if ( Number ( localStorage . getItem ( 'dark' ) ) ) {
219259 document . body . classList . add ( 'theme_dark' ) ;
@@ -433,8 +473,7 @@ export default class Settings {
433473 popup ( e ) ;
434474 }
435475 }
436- async uploadFile ( ) {
437- let file = this . $upload_file . files [ 0 ] ;
476+ async uploadFile ( file ) {
438477 this . $upload_file . value = "" ;
439478 let path = await AsyncPrompt ( "Upload" , '/' + file . name ) ;
440479 if ( ! path ) return ;
@@ -452,12 +491,12 @@ export default class Settings {
452491 if ( ok ) this . parse ( await this . send ( 'fs' ) ) ;
453492 this . restartPing ( ) ;
454493 }
455- async uploadOta ( ) {
494+ async uploadOta ( file ) {
495+ if ( ! file . name . endsWith ( this . $upload_ota . accept ) ) return ;
456496 if ( ! await AsyncConfirm ( "Update firmware?" ) ) return ;
457497 this . stopPing ( ) ;
458498 this . offline = true ;
459499
460- let file = this . $upload_ota . files [ 0 ] ;
461500 this . $upload_ota . value = "" ;
462501
463502 let data = new FormData ( ) ;
0 commit comments