aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/js
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/js')
-rw-r--r--frontend/js/public.js144
1 files changed, 144 insertions, 0 deletions
diff --git a/frontend/js/public.js b/frontend/js/public.js
new file mode 100644
index 0000000..c295a05
--- /dev/null
+++ b/frontend/js/public.js
@@ -0,0 +1,144 @@
1(function () {
2 'use strict';
3
4 /* global superagent */
5 /* global Vue */
6 /* global $ */
7 /* global filesize */
8
9 function sanitize(filePath) {
10 filePath = '/' + filePath;
11 return filePath.replace(/\/+/g, '/');
12 }
13
14 function encode(filePath) {
15 return filePath.split('/').map(encodeURIComponent).join('/');
16 }
17
18 function decode(filePath) {
19 return filePath.split('/').map(decodeURIComponent).join('/');
20 }
21
22 var mimeTypes = {
23 images: [ '.png', '.jpg', '.jpeg', '.tiff', '.gif' ],
24 text: [ '.txt', '.md' ],
25 pdf: [ '.pdf' ],
26 html: [ '.html', '.htm', '.php' ],
27 video: [ '.mp4', '.mpg', '.mpeg', '.ogg', '.mkv', '.avi', '.mov' ]
28 };
29
30 function getPreviewUrl(entry, basePath) {
31 var path = '/_admin/img/';
32
33 if (entry.isDirectory) return path + 'directory.png';
34 if (mimeTypes.images.some(function (e) { return entry.filePath.endsWith(e); })) return sanitize(basePath + '/' + entry.filePath);
35 if (mimeTypes.text.some(function (e) { return entry.filePath.endsWith(e); })) return path +'text.png';
36 if (mimeTypes.pdf.some(function (e) { return entry.filePath.endsWith(e); })) return path + 'pdf.png';
37 if (mimeTypes.html.some(function (e) { return entry.filePath.endsWith(e); })) return path + 'html.png';
38 if (mimeTypes.video.some(function (e) { return entry.filePath.endsWith(e); })) return path + 'video.png';
39
40 return path + 'unknown.png';
41 }
42
43 // simple extension detection, does not work with double extension like .tar.gz
44 function getExtension(entry) {
45 if (entry.isFile) return entry.filePath.slice(entry.filePath.lastIndexOf('.') + 1);
46 return '';
47 }
48
49 function loadDirectory() {
50 app.busy = true;
51
52 var filePath = sanitize(window.location.pathname);
53
54 app.path = filePath;
55
56 superagent.get('/api/files/' + encode(filePath)).query({ access_token: localStorage.accessToken }).end(function (error, result) {
57 app.busy = false;
58
59 if (result && result.statusCode === 401) return logout();
60 if (error) return console.error(error);
61
62 result.body.entries.sort(function (a, b) { return a.isDirectory && b.isFile ? -1 : 1; });
63 app.entries = result.body.entries.map(function (entry) {
64 entry.previewUrl = getPreviewUrl(entry, filePath);
65 entry.extension = getExtension(entry);
66 entry.rename = false;
67 entry.filePathNew = entry.filePath;
68 return entry;
69 });
70 app.path = filePath;
71 app.pathParts = decode(filePath).split('/').filter(function (e) { return !!e; }).map(function (e, i, a) {
72 return {
73 name: e,
74 link: '#' + sanitize('/' + a.slice(0, i).join('/') + '/' + e)
75 };
76 });
77 });
78 }
79
80 function open(row, column, event) {
81 var fullPath = encode(sanitize(app.path + '/' + row.filePath));
82
83 if (row.isDirectory) return window.location.href = fullPath;
84
85 app.activeEntry = row;
86 app.activeEntry.fullPath = fullPath;
87 app.previewDrawerVisible = true
88
89 // need to wait for DOM element to exist
90 setTimeout(function () {
91 $('iframe').on('load', function (e) {
92 if (!e.target.contentWindow.document.body) return;
93
94 e.target.contentWindow.document.body.style.display = 'flex'
95 e.target.contentWindow.document.body.style.justifyContent = 'center'
96 });
97 }, 0);
98 }
99
100 var app = new Vue({
101 el: '#app',
102 data: {
103 ready: false,
104 busy: false,
105 path: '',
106 previewDrawerVisible: false,
107 activeEntry: {},
108 entries: []
109 },
110 methods: {
111 onDownload: function (entry) {
112 if (entry.isDirectory) return;
113 window.location.href = encode('/api/files/' + sanitize(this.path + '/' + entry.filePath)) + '?access_token=' + localStorage.accessToken;
114 },
115 prettyDate: function (row, column, cellValue, index) {
116 var date = new Date(cellValue),
117 diff = (((new Date()).getTime() - date.getTime()) / 1000),
118 day_diff = Math.floor(diff / 86400);
119
120 if (isNaN(day_diff) || day_diff < 0)
121 return;
122
123 return day_diff === 0 && (
124 diff < 60 && 'just now' ||
125 diff < 120 && '1 minute ago' ||
126 diff < 3600 && Math.floor( diff / 60 ) + ' minutes ago' ||
127 diff < 7200 && '1 hour ago' ||
128 diff < 86400 && Math.floor( diff / 3600 ) + ' hours ago') ||
129 day_diff === 1 && 'Yesterday' ||
130 day_diff < 7 && day_diff + ' days ago' ||
131 day_diff < 31 && Math.ceil( day_diff / 7 ) + ' weeks ago' ||
132 day_diff < 365 && Math.round( day_diff / 30 ) + ' months ago' ||
133 Math.round( day_diff / 365 ) + ' years ago';
134 },
135 prettyFileSize: function (row, column, cellValue, index) {
136 return filesize(cellValue);
137 },
138 loadDirectory: loadDirectory,
139 open: open,
140 }
141 });
142
143 loadDirectory();
144})(); \ No newline at end of file