]> git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/blame - frontend/js/app.js
Add rename functionality
[perso/Immae/Projets/Nodejs/Surfer.git] / frontend / js / app.js
CommitLineData
6eb72d64
JZ
1(function () {
2'use strict';
3
4function login(username, password) {
5 username = username || app.loginData.username;
6 password = password || app.loginData.password;
7
8 app.busy = true;
9
10 superagent.get('/api/files/').query({ username: username, password: password }).end(function (error, result) {
11 app.busy = false;
12
13 if (error) return console.error(error);
14 if (result.statusCode === 401) return console.error('Invalid credentials');
15
16 app.session.valid = true;
17 app.session.username = username;
18 app.session.password = password;
19
20 // clearly not the best option
21 localStorage.username = username;
22 localStorage.password = password;
d3312ed1 23
04bc2989 24 loadDirectory(window.location.hash.slice(1));
6eb72d64
JZ
25 });
26}
27
28function logout() {
29 app.session.valid = false;
95c627bf
JZ
30 app.session.username = null;
31 app.session.password = null;
6eb72d64
JZ
32
33 delete localStorage.username;
34 delete localStorage.password;
35}
36
d3312ed1
JZ
37function sanitize(filePath) {
38 filePath = '/' + filePath;
39 return filePath.replace(/\/+/g, '/');
40}
41
537bfb04
JZ
42function encode(filePath) {
43 return filePath.split('/').map(encodeURIComponent).join('/');
44}
45
04bc2989
JZ
46function decode(filePath) {
47 return filePath.split('/').map(decodeURIComponent).join('/');
48}
49
a26d1f9b
JZ
50var mimeTypes = {
51 images: [ '.png', '.jpg', '.jpeg', '.tiff', '.gif' ],
52 text: [ '.txt', '.md' ],
53 pdf: [ '.pdf' ],
54 html: [ '.html', '.htm', '.php' ],
55 video: [ '.mp4', '.mpg', '.mpeg', '.ogg', '.mkv' ]
56};
57
58function getPreviewUrl(entry, basePath) {
59 var path = '/_admin/img/';
60
61 if (entry.isDirectory) return path + 'directory.png';
62 if (mimeTypes.images.some(function (e) { return entry.filePath.endsWith(e); })) return sanitize(basePath + '/' + entry.filePath);
63 if (mimeTypes.text.some(function (e) { return entry.filePath.endsWith(e); })) return path +'text.png';
64 if (mimeTypes.pdf.some(function (e) { return entry.filePath.endsWith(e); })) return path + 'pdf.png';
65 if (mimeTypes.html.some(function (e) { return entry.filePath.endsWith(e); })) return path + 'html.png';
66 if (mimeTypes.video.some(function (e) { return entry.filePath.endsWith(e); })) return path + 'video.png';
67
68 return path + 'unknown.png';
69}
70
537bfb04
JZ
71function refresh() {
72 loadDirectory(app.path);
73}
74
d3312ed1
JZ
75function loadDirectory(filePath) {
76 app.busy = true;
77
78 filePath = filePath ? sanitize(filePath) : '/';
79
51723cdf 80 superagent.get('/api/files/' + encode(filePath)).query({ username: app.session.username, password: app.session.password }).end(function (error, result) {
d3312ed1
JZ
81 app.busy = false;
82
9209abec 83 if (result && result.statusCode === 401) return logout();
d3312ed1 84 if (error) return console.error(error);
d3312ed1 85
04bc2989 86 result.body.entries.sort(function (a, b) { return a.isDirectory && b.isFile ? -1 : 1; });
a26d1f9b
JZ
87 app.entries = result.body.entries.map(function (entry) {
88 entry.previewUrl = getPreviewUrl(entry, filePath);
89 return entry;
90 });
d3312ed1 91 app.path = filePath;
51723cdf
J
92 app.pathParts = decode(filePath).split('/').filter(function (e) { return !!e; }).map(function (e, i, a) {
93 return {
94 name: e,
95 link: '#' + sanitize('/' + a.slice(0, i).join('/') + '/' + e)
96 };
97 });
04bc2989
JZ
98
99 // update in case this was triggered from code
100 window.location.hash = app.path;
3e98fb0c
JZ
101
102 Vue.nextTick(function () {
103 $(function () {
104 $('[data-toggle="tooltip"]').tooltip();
105 });
106 });
d3312ed1
JZ
107 });
108}
109
110function open(entry) {
5f43935e 111 var path = sanitize(app.path + '/' + entry.filePath);
d3312ed1 112
04bc2989
JZ
113 if (entry.isDirectory) {
114 window.location.hash = path;
115 return;
116 }
d3312ed1 117
5f43935e 118 window.open(encode(path));
d3312ed1
JZ
119}
120
121function up() {
5f43935e 122 window.location.hash = sanitize(app.path.split('/').slice(0, -1).filter(function (p) { return !!p; }).join('/'));
d3312ed1
JZ
123}
124
537bfb04 125function upload() {
403359cf 126 $(app.$els.upload).on('change', function () {
537bfb04 127
403359cf
JZ
128 // detach event handler
129 $(app.$els.upload).off('change');
130
fea6789c
JZ
131 app.uploadStatus = {
132 busy: true,
133 count: app.$els.upload.files.length,
134 done: 0,
135 percentDone: 0
136 };
537bfb04 137
ecfbca9f
J
138 function uploadFile(file) {
139 var path = encode(sanitize(app.path + '/' + file.name));
537bfb04 140
ecfbca9f
J
141 var formData = new FormData();
142 formData.append('file', file);
537bfb04 143
e628921a 144 superagent.post('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send(formData).end(function (error, result) {
ecfbca9f
J
145 if (result && result.statusCode === 401) return logout();
146 if (result && result.statusCode !== 201) console.error('Error uploading file: ', result.statusCode);
147 if (error) console.error(error);
537bfb04 148
fea6789c
JZ
149 app.uploadStatus.done += 1;
150 app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.count * 100);
151
fea6789c
JZ
152 if (app.uploadStatus.done >= app.uploadStatus.count) {
153 app.uploadStatus = {
154 busy: false,
155 count: 0,
156 done: 0,
157 percentDone: 100
158 };
ecfbca9f 159
ecfbca9f
J
160 refresh();
161 }
162 });
163 }
164
fea6789c 165 for(var i = 0; i < app.uploadStatus.count; ++i) {
ecfbca9f
J
166 uploadFile(app.$els.upload.files[i]);
167 }
537bfb04
JZ
168 });
169
e41fd8d8
JZ
170 // reset the form first to make the change handler retrigger even on the same file selected
171 $('#fileUploadForm')[0].reset();
172
537bfb04
JZ
173 app.$els.upload.click();
174}
175
9138d7d4
JZ
176function delAsk(entry) {
177 $('#modalDelete').modal('show');
178 app.deleteData = entry;
179}
180
181function del(entry) {
182 app.busy = true;
183
184 var path = encode(sanitize(app.path + '/' + entry.filePath));
185
186 superagent.del('/api/files' + path).query({ username: app.session.username, password: app.session.password, recursive: true }).end(function (error, result) {
187 app.busy = false;
188
9209abec
JZ
189 if (result && result.statusCode === 401) return logout();
190 if (result && result.statusCode !== 200) return console.error('Error deleting file: ', result.statusCode);
9138d7d4 191 if (error) return console.error(error);
9138d7d4
JZ
192
193 refresh();
194
195 $('#modalDelete').modal('hide');
196 });
197}
198
e628921a
JZ
199function renameAsk(entry) {
200 app.renameData.entry = entry;
201 app.renameData.error = null;
202 app.renameData.newFilePath = entry.filePath;
203
204 $('#modalRename').modal('show');
205}
206
207function rename(data) {
208 app.busy = true;
209
210 var path = encode(sanitize(app.path + '/' + data.entry.filePath));
211 var newFilePath = sanitize(app.path + '/' + data.newFilePath);
212
213 superagent.put('/api/files' + path).query({ username: app.session.username, password: app.session.password }).send({ newFilePath: newFilePath }).end(function (error, result) {
214 app.busy = false;
215
216 if (result && result.statusCode === 401) return logout();
217 if (result && result.statusCode !== 200) return console.error('Error renaming file: ', result.statusCode);
218 if (error) return console.error(error);
219
220 refresh();
221
222 $('#modalRename').modal('hide');
223 });
224}
225
403359cf
JZ
226function createDirectoryAsk() {
227 $('#modalcreateDirectory').modal('show');
228 app.createDirectoryData = '';
9209abec 229 app.createDirectoryError = null;
403359cf
JZ
230}
231
232function createDirectory(name) {
233 app.busy = true;
9209abec 234 app.createDirectoryError = null;
403359cf
JZ
235
236 var path = encode(sanitize(app.path + '/' + name));
237
e628921a 238 superagent.post('/api/files' + path).query({ username: app.session.username, password: app.session.password, directory: true }).end(function (error, result) {
403359cf
JZ
239 app.busy = false;
240
9209abec
JZ
241 if (result && result.statusCode === 401) return logout();
242 if (result && result.statusCode === 403) {
243 app.createDirectoryError = 'Name not allowed';
244 return;
245 }
246 if (result && result.statusCode === 409) {
247 app.createDirectoryError = 'Directory already exists';
248 return;
249 }
250 if (result && result.statusCode !== 201) return console.error('Error creating directory: ', result.statusCode);
403359cf 251 if (error) return console.error(error);
403359cf
JZ
252
253 app.createDirectoryData = '';
254 refresh();
255
256 $('#modalcreateDirectory').modal('hide');
257 });
258}
259
235212c4
JZ
260Vue.filter('prettyDate', function (value) {
261 var d = new Date(value);
262 return d.toDateString();
263});
264
8fce52f8
JZ
265Vue.filter('prettyFileSize', function (value) {
266 return filesize(value);
267});
268
6eb72d64
JZ
269var app = new Vue({
270 el: '#app',
271 data: {
272 busy: true,
fea6789c
JZ
273 uploadStatus: {
274 busy: false,
275 count: 0,
276 done: 0,
277 percentDone: 50
278 },
d3312ed1
JZ
279 path: '/',
280 pathParts: [],
6eb72d64
JZ
281 session: {
282 valid: false
283 },
d3312ed1 284 loginData: {},
9138d7d4 285 deleteData: {},
e628921a
JZ
286 renameData: {
287 entry: {},
288 error: null,
289 newFilePath: ''
290 },
403359cf 291 createDirectoryData: '',
9209abec 292 createDirectoryError: null,
d3312ed1 293 entries: []
6eb72d64
JZ
294 },
295 methods: {
296 login: login,
d3312ed1
JZ
297 logout: logout,
298 loadDirectory: loadDirectory,
299 open: open,
537bfb04 300 up: up,
9138d7d4
JZ
301 upload: upload,
302 delAsk: delAsk,
403359cf 303 del: del,
e628921a
JZ
304 renameAsk: renameAsk,
305 rename: rename,
403359cf
JZ
306 createDirectoryAsk: createDirectoryAsk,
307 createDirectory: createDirectory
6eb72d64
JZ
308 }
309});
310
9209abec
JZ
311window.app = app;
312
6eb72d64
JZ
313login(localStorage.username, localStorage.password);
314
04bc2989
JZ
315$(window).on('hashchange', function () {
316 loadDirectory(window.location.hash.slice(1));
317});
318
9209abec
JZ
319// setup all the dialog focus handling
320['modalcreateDirectory'].forEach(function (id) {
321 $('#' + id).on('shown.bs.modal', function () {
322 $(this).find("[autofocus]:first").focus();
323 });
324});
325
6eb72d64 326})();