aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohannes Zellner <johannes@nebulon.de>2016-03-01 15:10:25 +0100
committerJohannes Zellner <johannes@nebulon.de>2016-03-01 15:10:25 +0100
commitd3312ed1aace3c72570f60be56d846fb9ecbc584 (patch)
tree7c55ab933fae9c5577bd8f098da98da3cd5ad577
parent6eb72d64efc4a22aeb6cd5f52d1e4508ffed137f (diff)
downloadSurfer-d3312ed1aace3c72570f60be56d846fb9ecbc584.tar.gz
Surfer-d3312ed1aace3c72570f60be56d846fb9ecbc584.tar.zst
Surfer-d3312ed1aace3c72570f60be56d846fb9ecbc584.zip
Make directory listing navigatable
-rw-r--r--app/css/style.css4
-rw-r--r--app/index.html31
-rw-r--r--app/js/app.js51
3 files changed, 73 insertions, 13 deletions
diff --git a/app/css/style.css b/app/css/style.css
index c75e038..b7e5742 100644
--- a/app/css/style.css
+++ b/app/css/style.css
@@ -29,3 +29,7 @@ pre {
29[v-cloak] { 29[v-cloak] {
30 display: none; 30 display: none;
31} 31}
32
33.hand {
34 cursor: hand;
35} \ No newline at end of file
diff --git a/app/index.html b/app/index.html
index 5807724..773b5cf 100644
--- a/app/index.html
+++ b/app/index.html
@@ -2,6 +2,7 @@
2<head> 2<head>
3 <title> Cloudron Surfer </title> 3 <title> Cloudron Surfer </title>
4 4
5 <link rel="stylesheet" href="/admin/css/font-awesome.min.css">
5 <link rel="stylesheet" href="/admin/css/bootstrap.min.css"> 6 <link rel="stylesheet" href="/admin/css/bootstrap.min.css">
6 <link rel="stylesheet" href="/admin/css/style.css"> 7 <link rel="stylesheet" href="/admin/css/style.css">
7 8
@@ -63,27 +64,39 @@
63 <div class="row"> 64 <div class="row">
64 <div class="col-lg-12"> 65 <div class="col-lg-12">
65 <ol class="breadcrumb"> 66 <ol class="breadcrumb">
66 <li><a href="#">Home</a></li> 67 <li><i class="fa fa-home"></i>&nbsp;</li>
67 <li><a href="#">Library</a></li> 68 <li v-for="part in pathParts">
68 <li class="active">Data</li> 69 {{ part }}
70 </li>
69 </ol> 71 </ol>
70 </div> 72 </div>
71 <div class="col-lg-12"> 73 <div class="col-lg-12">
72 <table class="table table-hover"> 74 <table class="table table-hover table-condensed">
73 <thead> 75 <thead>
74 <tr> 76 <tr>
75 <th>Type</th> 77 <th>Type</th>
76 <th>Name</th> 78 <th>Name</th>
77 <th>Size</th> 79 <th>Size</th>
78 <th>Modified</th> 80 <th>Modified</th>
81 <th style="text-align: right;">Action</th>
79 </tr> 82 </tr>
80 </thead> 83 </thead>
81 <tbody> 84 <tbody>
82 <tr> 85 <tr v-show="path !== '/'" v-on:click="up()" class="hand">
83 <th>Type</th> 86 <th><i class="fa fa-chevron-up"></i></th>
84 <th>Name</th> 87 <th>..</th>
85 <th>Size</th> 88 <th></th>
86 <th>Modified</th> 89 <th></th>
90 </tr>
91 <tr v-for="entry in entries" v-on:click="open(entry)" class="hand">
92 <th>
93 <i class="fa fa-folder-o" v-show="entry.isDirectory"></i>
94 <i class="fa fa-file-o" v-show="entry.isFile"></i>
95 </th>
96 <th>{{ entry.filePath }}</th>
97 <th>{{ entry.size }}</th>
98 <th>{{ entry.mtime }}</th>
99 <th style="text-align: right;"><button class="btn btn-sm btn-danger"><i class="fa fa-trash"></i></button></th>
87 </tr> 100 </tr>
88 </tbody> 101 </tbody>
89 </table> 102 </table>
diff --git a/app/js/app.js b/app/js/app.js
index 55153d4..10a489c 100644
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -20,6 +20,8 @@ function login(username, password) {
20 // clearly not the best option 20 // clearly not the best option
21 localStorage.username = username; 21 localStorage.username = username;
22 localStorage.password = password; 22 localStorage.password = password;
23
24 loadDirectory(app.path);
23 }); 25 });
24} 26}
25 27
@@ -32,20 +34,61 @@ function logout() {
32 delete localStorage.password; 34 delete localStorage.password;
33} 35}
34 36
37function sanitize(filePath) {
38 filePath = '/' + filePath;
39 return filePath.replace(/\/+/g, '/');
40}
41
42function loadDirectory(filePath) {
43 app.busy = true;
44
45 filePath = filePath ? sanitize(filePath) : '/';
46
47 console.log(filePath);
48
49 superagent.get('/api/files/' + filePath).query({ username: app.session.username, password: app.session.password }).end(function (error, result) {
50 app.busy = false;
51
52 if (error) return console.error(error);
53 if (result.statusCode === 401) return logout();
54
55 app.entries = result.body.entries;
56 app.path = filePath;
57 app.pathParts = filePath.split('/').filter(function (e) { return !!e; });
58 console.log(app.pathParts)
59 });
60}
61
62function open(entry) {
63 var path = sanitize(app.path + '/' + entry.filePath);
64
65 if (entry.isDirectory) return loadDirectory(path);
66
67 window.location.href = window.location.origin + path;
68}
69
70function up() {
71 loadDirectory(app.path.split('/').slice(0, -1).filter(function (p) { return !!p; }).join('/'));
72}
73
35var app = new Vue({ 74var app = new Vue({
36 el: '#app', 75 el: '#app',
37 data: { 76 data: {
38 busy: true, 77 busy: true,
78 path: '/',
79 pathParts: [],
39 session: { 80 session: {
40 valid: false 81 valid: false
41 }, 82 },
42 loginData: { 83 loginData: {},
43 84 entries: []
44 }
45 }, 85 },
46 methods: { 86 methods: {
47 login: login, 87 login: login,
48 logout: logout 88 logout: logout,
89 loadDirectory: loadDirectory,
90 open: open,
91 up: up
49 } 92 }
50}); 93});
51 94