]>
git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/blob - frontend/js/app.js
4 function getProfile ( accessToken
, callback
) {
5 callback
= callback
|| function ( error
) { if ( error
) console
. error ( error
); };
7 superagent
. get ( '/api/profile' ). query ({ access_token : accessToken
}). end ( function ( error
, result
) {
11 if ( error
&& ! error
. response
) return callback ( error
);
12 if ( result
. statusCode
!== 200 ) {
13 delete localStorage
. accessToken
;
14 return callback ( 'Invalid access token' );
17 localStorage
. accessToken
= accessToken
;
18 app
. session
. username
= result
. body
. username
;
19 app
. session
. valid
= true ;
25 function sanitize ( filePath
) {
26 filePath
= '/' + filePath
;
27 return filePath
. replace ( /\/+/g , '/' );
30 function encode ( filePath
) {
31 return filePath
. split ( '/' ). map ( encodeURIComponent
). join ( '/' );
34 function decode ( filePath
) {
35 return filePath
. split ( '/' ). map ( decodeURIComponent
). join ( '/' );
39 images : [ '.png' , '.jpg' , '.jpeg' , '.tiff' , '.gif' ],
40 text : [ '.txt' , '.md' ],
42 html : [ '.html' , '.htm' , '.php' ],
43 video : [ '.mp4' , '.mpg' , '.mpeg' , '.ogg' , '.mkv' ]
46 function getPreviewUrl ( entry
, basePath
) {
47 var path
= '/_admin/img/' ;
49 if ( entry
. isDirectory
) return path
+ 'directory.png' ;
50 if ( mimeTypes
. images
. some ( function ( e
) { return entry
. filePath
. endsWith ( e
); })) return sanitize ( basePath
+ '/' + entry
. filePath
);
51 if ( mimeTypes
. text
. some ( function ( e
) { return entry
. filePath
. endsWith ( e
); })) return path
+ 'text.png' ;
52 if ( mimeTypes
. pdf
. some ( function ( e
) { return entry
. filePath
. endsWith ( e
); })) return path
+ 'pdf.png' ;
53 if ( mimeTypes
. html
. some ( function ( e
) { return entry
. filePath
. endsWith ( e
); })) return path
+ 'html.png' ;
54 if ( mimeTypes
. video
. some ( function ( e
) { return entry
. filePath
. endsWith ( e
); })) return path
+ 'video.png' ;
56 return path
+ 'unknown.png' ;
59 // simple extension detection, does not work with double extension like .tar.gz
60 function getExtension ( entry
) {
61 if ( entry
. isFile
) return entry
. filePath
. slice ( entry
. filePath
. lastIndexOf ( '.' ) + 1 );
66 loadDirectory ( app
. path
);
69 function loadDirectory ( filePath
) {
72 filePath
= filePath
? sanitize ( filePath
) : '/' ;
74 superagent
. get ( '/api/files/' + encode ( filePath
)). query ({ access_token : localStorage
. accessToken
}). end ( function ( error
, result
) {
77 if ( result
&& result
. statusCode
=== 401 ) return logout ();
78 if ( error
) return console
. error ( error
);
80 result
. body
. entries
. sort ( function ( a
, b
) { return a
. isDirectory
&& b
. isFile
? - 1 : 1 ; });
81 app
. entries
= result
. body
. entries
. map ( function ( entry
) {
82 entry
. previewUrl
= getPreviewUrl ( entry
, filePath
);
83 entry
. extension
= getExtension ( entry
);
87 app
. pathParts
= decode ( filePath
). split ( '/' ). filter ( function ( e
) { return !! e
; }). map ( function ( e
, i
, a
) {
90 link : '#' + sanitize ( '/' + a
. slice ( 0 , i
). join ( '/' ) + '/' + e
)
94 // update in case this was triggered from code
95 window
. location
. hash
= app
. path
;
99 function open ( row
, event
, column
) {
100 var path
= sanitize ( app
. path
+ '/' + row
. filePath
);
102 if ( row
. isDirectory
) {
103 window
. location
. hash
= path
;
107 window
. open ( encode ( path
));
111 window
. location
. hash
= sanitize ( app
. path
. split ( '/' ). slice ( 0 , - 1 ). filter ( function ( p
) { return !! p
; }). join ( '/' ));
114 function uploadFiles ( files
) {
115 if (! files
|| ! files
. length
) return ;
124 function uploadFile ( file
) {
125 var path
= encode ( sanitize ( app
. path
+ '/' + file
. name
));
127 var formData
= new FormData ();
128 formData
. append ( 'file' , file
);
130 superagent
. post ( '/api/files' + path
). query ({ access_token : localStorage
. accessToken
}). send ( formData
). end ( function ( error
, result
) {
131 if ( result
&& result
. statusCode
=== 401 ) return logout ();
132 if ( result
&& result
. statusCode
!== 201 ) console
. error ( 'Error uploading file: ' , result
. statusCode
);
133 if ( error
) console
. error ( error
);
135 app
. uploadStatus
. done
+= 1 ;
136 app
. uploadStatus
. percentDone
= Math
. round ( app
. uploadStatus
. done
/ app
. uploadStatus
. count
* 100 );
138 if ( app
. uploadStatus
. done
>= app
. uploadStatus
. count
) {
151 for ( var i
= 0 ; i
< app
. uploadStatus
. count
; ++ i
) {
152 uploadFile ( files
[ i
]);
156 function dragOver ( event
) {
157 event
. preventDefault ();
160 function drop ( event
) {
161 event
. preventDefault ();
162 uploadFiles ( event
. dataTransfer
. files
|| []);
181 folderListingEnabled : false ,
189 onLogin : function () {
192 superagent
. post ( '/api/login' ). send ({ username : app
. loginData
. username
, password : app
. loginData
. password
}). end ( function ( error
, result
) {
195 if ( error
) return console
. error ( error
);
196 if ( result
. statusCode
=== 401 ) return console
. error ( 'Invalid credentials' );
198 getProfile ( result
. body
. accessToken
, function ( error
) {
199 if ( error
) return console
. error ( error
);
201 loadDirectory ( window
. location
. hash
. slice ( 1 ));
205 onOptionsMenu : function ( command
) {
206 if ( command
=== 'folderListing' ) {
207 console
. log ( 'Not implemented' );
208 } else if ( command
=== 'about' ) {
210 title : 'About Surfer' ,
211 message : 'Surfer is a static file server written by <a href="https://cloudron.io" target="_blank">Cloudron</a>.<br/><br/>The source code is licensed under MIT and available <a href="https://git.cloudron.io/cloudron/surfer" target="_blank">here</a>.' ,
212 dangerouslyUseHTMLString : true ,
213 confirmButtonText : 'OK' ,
214 showCancelButton : false ,
217 }). then ( function () {}). catch ( function () {});
218 } else if ( command
=== 'logout' ) {
219 superagent
. post ( '/api/logout' ). query ({ access_token : localStorage
. accessToken
}). end ( function ( error
) {
220 if ( error
) console
. error ( error
);
222 app
. session
. valid
= false ;
224 delete localStorage
. accessToken
;
228 onDownload : function ( entry
) {
229 if ( entry
. isDirectory
) return ;
230 window
. location
. href
= encode ( '/api/files/' + sanitize ( app
. path
+ '/' + entry
. filePath
)) + '?access_token=' + localStorage
. accessToken
;
232 onUpload : function () {
233 $( app
.$ refs
. upload
). on ( 'change' , function () {
235 // detach event handler
236 $( app
.$ refs
. upload
). off ( 'change' );
238 uploadFiles ( app
.$ refs
. upload
. files
|| []);
241 // reset the form first to make the change handler retrigger even on the same file selected
242 app
.$ refs
. upload
. value
= '' ;
243 app
.$ refs
. upload
. click ();
245 onDelete : function ( entry
) {
246 var title
= 'Really delete ' + ( entry
. isDirectory
? 'folder ' : '' ) + entry
. filePath
;
247 this .$ confirm ( '' , title
, { confirmButtonText : 'Yes' , cancelButtonText : 'No' }). then ( function () {
248 var path
= encode ( sanitize ( app
. path
+ '/' + entry
. filePath
));
250 superagent
. del ( '/api/files' + path
). query ({ access_token : localStorage
. accessToken
, recursive : true }). end ( function ( error
, result
) {
251 if ( result
&& result
. statusCode
=== 401 ) return logout ();
252 if ( result
&& result
. statusCode
!== 200 ) return console
. error ( 'Error deleting file: ' , result
. statusCode
);
253 if ( error
) return console
. error ( error
);
257 }). catch ( function () {
258 console
. log ( 'delete error:' , arguments
);
261 onRename : function ( entry
) {
262 var title
= 'Rename ' + entry
. filePath
;
263 this .$ prompt ( '' , title
, { confirmButtonText : 'Yes' , cancelButtonText : 'No' , inputPlaceholder : 'new filename' , inputValue : entry
. filePath
}). then ( function ( data
) {
264 var path
= encode ( sanitize ( app
. path
+ '/' + entry
. filePath
));
265 var newFilePath
= sanitize ( app
. path
+ '/' + data
. value
);
267 superagent
. put ( '/api/files' + path
). query ({ access_token : localStorage
. accessToken
}). send ({ newFilePath : newFilePath
}). end ( function ( error
, result
) {
268 if ( result
&& result
. statusCode
=== 401 ) return logout ();
269 if ( result
&& result
. statusCode
!== 200 ) return console
. error ( 'Error renaming file: ' , result
. statusCode
);
270 if ( error
) return console
. error ( error
);
274 }). catch ( function () {
275 console
. log ( 'rename error:' , arguments
);
278 onNewFolder : function () {
279 var title
= 'Create New Folder' ;
280 this .$ prompt ( '' , title
, { confirmButtonText : 'Yes' , cancelButtonText : 'No' , inputPlaceholder : 'new foldername' }). then ( function ( data
) {
281 var path
= encode ( sanitize ( app
. path
+ '/' + data
. value
));
283 superagent
. post ( '/api/files' + path
). query ({ access_token : localStorage
. accessToken
, directory : true }). end ( function ( error
, result
) {
284 if ( result
&& result
. statusCode
=== 401 ) return logout ();
285 if ( result
&& result
. statusCode
=== 403 ) return console
. error ( 'Name not allowed' );
286 if ( result
&& result
. statusCode
=== 409 ) return console
. error ( 'Directory already exists' );
287 if ( result
&& result
. statusCode
!== 201 ) return console
. error ( 'Error creating directory: ' , result
. statusCode
);
288 if ( error
) return console
. error ( error
);
292 }). catch ( function () {
293 console
. log ( 'create folder error:' , arguments
);
296 prettyDate : function ( row
, column
, cellValue
, index
) {
297 var date
= new Date ( cellValue
),
298 diff
= ((( new Date ()). getTime () - date
. getTime ()) / 1000 ),
299 day_diff
= Math
. floor ( diff
/ 86400 );
301 if ( isNaN ( day_diff
) || day_diff
< 0 )
304 return day_diff
=== 0 && (
305 diff
< 60 && 'just now' ||
306 diff
< 120 && '1 minute ago' ||
307 diff
< 3600 && Math
. floor ( diff
/ 60 ) + ' minutes ago' ||
308 diff
< 7200 && '1 hour ago' ||
309 diff
< 86400 && Math
. floor ( diff
/ 3600 ) + ' hours ago' ) ||
310 day_diff
=== 1 && 'Yesterday' ||
311 day_diff
< 7 && day_diff
+ ' days ago' ||
312 day_diff
< 31 && Math
. ceil ( day_diff
/ 7 ) + ' weeks ago' ||
313 day_diff
< 365 && Math
. round ( day_diff
/ 30 ) + ' months ago' ||
314 Math
. round ( day_diff
/ 365 ) + ' years ago' ;
316 prettyFileSize : function ( row
, column
, cellValue
, index
) {
317 return filesize ( cellValue
);
319 loadDirectory : loadDirectory
,
327 getProfile ( localStorage
. accessToken
, function ( error
) {
328 if ( error
) return console
. error ( error
);
330 loadDirectory ( window
. location
. hash
. slice ( 1 ));
333 $( window
). on ( 'hashchange' , function () {
334 loadDirectory ( window
. location
. hash
. slice ( 1 ));