]>
Commit | Line | Data |
---|---|---|
313dfe99 JZ |
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 | })(); |