]>
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
) {
10 if (error
&& !error
.response
) return callback(error
);
11 if (result
.statusCode
!== 200) {
12 delete localStorage
.accessToken
;
13 return callback('Invalid access token');
16 localStorage
.accessToken
= accessToken
;
17 app
.session
.username
= result
.body
.username
;
18 app
.session
.valid
= true;
24 function login(username
, password
) {
25 username
= username
|| app
.loginData
.username
;
26 password
= password
|| app
.loginData
.password
;
30 superagent
.post('/api/login').send({ username: username
, password: password
}).end(function (error
, result
) {
33 if (error
) return console
.error(error
);
34 if (result
.statusCode
=== 401) return console
.error('Invalid credentials');
36 getProfile(result
.body
.accessToken
, function (error
) {
37 if (error
) return console
.error(error
);
39 loadDirectory(window
.location
.hash
.slice(1));
45 superagent
.post('/api/logout').query({ access_token: localStorage
.accessToken
}).end(function (error
) {
46 if (error
) console
.error(error
);
48 app
.session
.valid
= false;
50 delete localStorage
.accessToken
;
54 function sanitize(filePath
) {
55 filePath
= '/' + filePath
;
56 return filePath
.replace(/\/+/g, '/');
59 function encode(filePath
) {
60 return filePath
.split('/').map(encodeURIComponent
).join('/');
63 function decode(filePath
) {
64 return filePath
.split('/').map(decodeURIComponent
).join('/');
68 images: [ '.png', '.jpg', '.jpeg', '.tiff', '.gif' ],
69 text: [ '.txt', '.md' ],
71 html: [ '.html', '.htm', '.php' ],
72 video: [ '.mp4', '.mpg', '.mpeg', '.ogg', '.mkv' ]
75 function getPreviewUrl(entry
, basePath
) {
76 var path
= '/_admin/img/';
78 if (entry
.isDirectory
) return path
+ 'directory.png';
79 if (mimeTypes
.images
.some(function (e
) { return entry
.filePath
.endsWith(e
); })) return sanitize(basePath
+ '/' + entry
.filePath
);
80 if (mimeTypes
.text
.some(function (e
) { return entry
.filePath
.endsWith(e
); })) return path
+'text.png';
81 if (mimeTypes
.pdf
.some(function (e
) { return entry
.filePath
.endsWith(e
); })) return path
+ 'pdf.png';
82 if (mimeTypes
.html
.some(function (e
) { return entry
.filePath
.endsWith(e
); })) return path
+ 'html.png';
83 if (mimeTypes
.video
.some(function (e
) { return entry
.filePath
.endsWith(e
); })) return path
+ 'video.png';
85 return path
+ 'unknown.png';
88 // simple extension detection, does not work with double extension like .tar.gz
89 function getExtension(entry
) {
90 if (entry
.isFile
) return entry
.filePath
.slice(entry
.filePath
.lastIndexOf('.') + 1);
95 loadDirectory(app
.path
);
98 function loadDirectory(filePath
) {
101 filePath
= filePath
? sanitize(filePath
) : '/';
103 superagent
.get('/api/files/' + encode(filePath
)).query({ access_token: localStorage
.accessToken
}).end(function (error
, result
) {
106 if (result
&& result
.statusCode
=== 401) return logout();
107 if (error
) return console
.error(error
);
109 result
.body
.entries
.sort(function (a
, b
) { return a
.isDirectory
&& b
.isFile
? -1 : 1; });
110 app
.entries
= result
.body
.entries
.map(function (entry
) {
111 entry
.previewUrl
= getPreviewUrl(entry
, filePath
);
112 entry
.extension
= getExtension(entry
);
116 app
.pathParts
= decode(filePath
).split('/').filter(function (e
) { return !!e
; }).map(function (e
, i
, a
) {
119 link: '#' + sanitize('/' + a
.slice(0, i
).join('/') + '/' + e
)
123 // update in case this was triggered from code
124 window
.location
.hash
= app
.path
;
126 Vue
.nextTick(function () {
128 $('[data-toggle="tooltip"]').tooltip();
134 function open(entry
) {
135 var path
= sanitize(app
.path
+ '/' + entry
.filePath
);
137 if (entry
.isDirectory
) {
138 window
.location
.hash
= path
;
142 window
.open(encode(path
));
145 function download(entry
) {
146 if (entry
.isDirectory
) return;
148 window
.location
.href
= encode('/api/files/' + sanitize(app
.path
+ '/' + entry
.filePath
)) + '?access_token=' + localStorage
.accessToken
;
152 window
.location
.hash
= sanitize(app
.path
.split('/').slice(0, -1).filter(function (p
) { return !!p
; }).join('/'));
155 function uploadFiles(files
) {
156 if (!files
|| !files
.length
) return;
165 function uploadFile(file
) {
166 var path
= encode(sanitize(app
.path
+ '/' + file
.name
));
168 var formData
= new FormData();
169 formData
.append('file', file
);
171 superagent
.post('/api/files' + path
).query({ access_token: localStorage
.accessToken
}).send(formData
).end(function (error
, result
) {
172 if (result
&& result
.statusCode
=== 401) return logout();
173 if (result
&& result
.statusCode
!== 201) console
.error('Error uploading file: ', result
.statusCode
);
174 if (error
) console
.error(error
);
176 app
.uploadStatus
.done
+= 1;
177 app
.uploadStatus
.percentDone
= Math
.round(app
.uploadStatus
.done
/ app
.uploadStatus
.count
* 100);
179 if (app
.uploadStatus
.done
>= app
.uploadStatus
.count
) {
192 for(var i
= 0; i
< app
.uploadStatus
.count
; ++i
) {
193 uploadFile(files
[i
]);
198 $(app
.$els
.upload
).on('change', function () {
200 // detach event handler
201 $(app
.$els
.upload
).off('change');
203 uploadFiles(app
.$els
.upload
.files
|| []);
206 // reset the form first to make the change handler retrigger even on the same file selected
207 $('#fileUploadForm')[0].reset();
209 app
.$els
.upload
.click();
212 function delAsk(entry
) {
213 $('#modalDelete').modal('show');
214 app
.deleteData
= entry
;
217 function del(entry
) {
220 var path
= encode(sanitize(app
.path
+ '/' + entry
.filePath
));
222 superagent
.del('/api/files' + path
).query({ access_token: localStorage
.accessToken
, recursive: true }).end(function (error
, result
) {
225 if (result
&& result
.statusCode
=== 401) return logout();
226 if (result
&& result
.statusCode
!== 200) return console
.error('Error deleting file: ', result
.statusCode
);
227 if (error
) return console
.error(error
);
231 $('#modalDelete').modal('hide');
235 function renameAsk(entry
) {
236 app
.renameData
.entry
= entry
;
237 app
.renameData
.error
= null;
238 app
.renameData
.newFilePath
= entry
.filePath
;
240 $('#modalRename').modal('show');
243 function rename(data
) {
246 var path
= encode(sanitize(app
.path
+ '/' + data
.entry
.filePath
));
247 var newFilePath
= sanitize(app
.path
+ '/' + data
.newFilePath
);
249 superagent
.put('/api/files' + path
).query({ access_token: localStorage
.accessToken
}).send({ newFilePath: newFilePath
}).end(function (error
, result
) {
252 if (result
&& result
.statusCode
=== 401) return logout();
253 if (result
&& result
.statusCode
!== 200) return console
.error('Error renaming file: ', result
.statusCode
);
254 if (error
) return console
.error(error
);
258 $('#modalRename').modal('hide');
262 function createDirectoryAsk() {
263 $('#modalcreateDirectory').modal('show');
264 app
.createDirectoryData
= '';
265 app
.createDirectoryError
= null;
268 function createDirectory(name
) {
270 app
.createDirectoryError
= null;
272 var path
= encode(sanitize(app
.path
+ '/' + name
));
274 superagent
.post('/api/files' + path
).query({ access_token: localStorage
.accessToken
, directory: true }).end(function (error
, result
) {
277 if (result
&& result
.statusCode
=== 401) return logout();
278 if (result
&& result
.statusCode
=== 403) {
279 app
.createDirectoryError
= 'Name not allowed';
282 if (result
&& result
.statusCode
=== 409) {
283 app
.createDirectoryError
= 'Directory already exists';
286 if (result
&& result
.statusCode
!== 201) return console
.error('Error creating directory: ', result
.statusCode
);
287 if (error
) return console
.error(error
);
289 app
.createDirectoryData
= '';
292 $('#modalcreateDirectory').modal('hide');
296 function dragOver(event
) {
297 event
.preventDefault();
300 function drop(event
) {
301 event
.preventDefault();
302 uploadFiles(event
.dataTransfer
.files
|| []);
305 Vue
.filter('prettyDate', function (value
) {
306 var d
= new Date(value
);
307 return d
.toDateString();
310 Vue
.filter('prettyFileSize', function (value
) {
311 return filesize(value
);
336 createDirectoryData: '',
337 createDirectoryError: null,
343 loadDirectory: loadDirectory
,
350 renameAsk: renameAsk
,
352 createDirectoryAsk: createDirectoryAsk
,
353 createDirectory: createDirectory
,
361 getProfile(localStorage
.accessToken
, function (error
) {
362 if (error
) return console
.error(error
);
364 loadDirectory(window
.location
.hash
.slice(1));
367 $(window
).on('hashchange', function () {
368 loadDirectory(window
.location
.hash
.slice(1));
371 // setup all the dialog focus handling
372 ['modalcreateDirectory'].forEach(function (id
) {
373 $('#' + id
).on('shown.bs.modal', function () {
374 $(this).find("[autofocus]:first").focus();