aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--frontend/css/style.css2
-rw-r--r--frontend/index.html62
-rw-r--r--frontend/js/app.js57
3 files changed, 64 insertions, 57 deletions
diff --git a/frontend/css/style.css b/frontend/css/style.css
index 5c9236b..45fce56 100644
--- a/frontend/css/style.css
+++ b/frontend/css/style.css
@@ -23,7 +23,7 @@ body {
23.el-footer { 23.el-footer {
24 padding: 3px 20px; 24 padding: 3px 20px;
25 font-size: 14px; 25 font-size: 14px;
26 text-align: center; 26 height: 38px !important;
27} 27}
28 28
29a { 29a {
diff --git a/frontend/index.html b/frontend/index.html
index 2e2e5e3..15e5d98 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -70,47 +70,43 @@
70 </el-header> 70 </el-header>
71 <el-main> 71 <el-main>
72 72
73 <!-- <div class="container" v-show="uploadStatus.busy" v-cloak>
74 <div class="row">
75 <div class="col-lg-12">
76 <p>Uploading... ({{ uploadStatus.done }} / {{ uploadStatus.count }}) </p>
77 <center>
78 <div class="progress">
79 <div class="progress-bar progress-bar-striped" role="progressbar" v-bind:style="{ width: uploadStatus.percentDone + '%' }">
80 <span class="sr-only">{{ uploadStatus.percentDone }}% Complete</span>
81 </div>
82 </div>
83 </center>
84 </div>
85 </div>
86 </div> -->
87
88 <div v-show="busy"> 73 <div v-show="busy">
89 <center><h1><i class="el-icon-loading"></i></h1></center> 74 <center><h1><i class="el-icon-loading"></i></h1></center>
90 </div> 75 </div>
91 76
92 <div v-show="!busy && session.valid" v-cloak> 77 <div v-show="!busy && session.valid" v-cloak>
93 <el-table :data="entries" style="width: 100%" height="100%" empty-text="Folder is emtpy" :default-sort="{ prop: 'filePath', order: 'descending' }" @row-click="open"> 78 <center>
94 <el-table-column prop="previewUrl" label="Type" width="100px" sortable> 79 <el-table :data="entries" style="max-width: 1280px;width: 100%" height="100%" empty-text="Folder is emtpy" :default-sort="{ prop: 'filePath', order: 'descending' }" @row-click="open">
95 <template slot-scope="scope"> 80 <el-table-column prop="previewUrl" label="Type" width="100px" sortable>
96 <img v-bind:src="scope.row.previewUrl" height="48px" width="48px"/> 81 <template slot-scope="scope">
97 </template> 82 <img v-bind:src="scope.row.previewUrl" height="48px" width="48px"/>
98 </el-table-column> 83 </template>
99 <el-table-column prop="filePath" label="Name" sortable></el-table-column> 84 </el-table-column>
100 <el-table-column prop="size" label="Size" width="150px" sortable :formatter="prettyFileSize"></el-table-column> 85 <el-table-column prop="filePath" label="Name" sortable></el-table-column>
101 <el-table-column prop="mtime" label="Modified" width="150px" sortable :formatter="prettyDate"></el-table-column> 86 <el-table-column prop="size" label="Size" width="150px" sortable :formatter="prettyFileSize"></el-table-column>
102 <el-table-column label="Actions" align="right" width="200px" class-name="list-actions"> 87 <el-table-column prop="mtime" label="Modified" width="150px" sortable :formatter="prettyDate"></el-table-column>
103 <template slot-scope="scope"> 88 <el-table-column label="Actions" align="right" width="200px" class-name="list-actions">
104 <el-button size="small" icon="el-icon-download" circle v-show="scope.row.isFile" @click.stop="onDownload(scope.row)"></el-button> 89 <template slot-scope="scope">
105 <el-button size="small" icon="el-icon-edit" circle @click.stop="onRename(scope.row)"></el-button> 90 <el-button size="small" icon="el-icon-download" circle v-show="scope.row.isFile" @click.stop="onDownload(scope.row)"></el-button>
106 <el-button size="small" icon="el-icon-delete" circle @click.stop="onDelete(scope.row)"></el-button> 91 <el-button size="small" icon="el-icon-edit" circle @click.stop="onRename(scope.row)"></el-button>
107 </template> 92 <el-button size="small" icon="el-icon-delete" circle @click.stop="onDelete(scope.row)"></el-button>
108 </el-table-column> 93 </template>
109 </el-table> 94 </el-table-column>
95 </el-table>
96 </center>
110 </div> 97 </div>
111 98
112 </el-main> 99 </el-main>
113 <el-footer style="height: 24px">Built by the <a href="https://cloudron.io" target="_blank">Cloudron.io</a> team. <a href="https://git.cloudron.io/cloudron/surfer" target="_blank">Get the code</a></el-footer> 100 <el-footer v-show="uploadStatus.busy">
101 <el-row>
102 <el-col :span="4">
103 Uploading files ({{ uploadStatus.done }} / {{ uploadStatus.count }})
104 </el-col>
105 <el-col :span="20">
106 <el-progress :text-inside="true" :stroke-width="18" :percentage="uploadStatus.percentDone"></el-progress>
107 </el-col>
108 </el-row>
109 </el-footer>
114</el-container> 110</el-container>
115 111
116</div> 112</div>
diff --git a/frontend/js/app.js b/frontend/js/app.js
index d659b18..1500457 100644
--- a/frontend/js/app.js
+++ b/frontend/js/app.js
@@ -1,6 +1,23 @@
1(function () { 1(function () {
2'use strict'; 2'use strict';
3 3
4// poor man's async
5function asyncForEach(items, handler, callback) {
6 var cur = 0;
7
8 if (items.length === 0) return callback();
9
10 (function iterator() {
11 handler(items[cur], function (error) {
12 if (error) return callback(error);
13 if (cur >= items.length-1) return callback();
14 ++cur;
15
16 iterator();
17 });
18 })();
19}
20
4function getProfile(accessToken, callback) { 21function getProfile(accessToken, callback) {
5 callback = callback || function (error) { if (error) console.error(error); }; 22 callback = callback || function (error) { if (error) console.error(error); };
6 23
@@ -114,14 +131,12 @@ function up() {
114function uploadFiles(files) { 131function uploadFiles(files) {
115 if (!files || !files.length) return; 132 if (!files || !files.length) return;
116 133
117 app.uploadStatus = { 134 app.uploadStatus.busy = true;
118 busy: true, 135 app.uploadStatus.count = files.length;
119 count: files.length, 136 app.uploadStatus.done = 0;
120 done: 0, 137 app.uploadStatus.percentDone = 0;
121 percentDone: 0
122 };
123 138
124 function uploadFile(file) { 139 asyncForEach(files, function (file, callback) {
125 var path = encode(sanitize(app.path + '/' + file.name)); 140 var path = encode(sanitize(app.path + '/' + file.name));
126 141
127 var formData = new FormData(); 142 var formData = new FormData();
@@ -129,28 +144,24 @@ function uploadFiles(files) {
129 144
130 superagent.post('/api/files' + path).query({ access_token: localStorage.accessToken }).send(formData).end(function (error, result) { 145 superagent.post('/api/files' + path).query({ access_token: localStorage.accessToken }).send(formData).end(function (error, result) {
131 if (result && result.statusCode === 401) return logout(); 146 if (result && result.statusCode === 401) return logout();
132 if (result && result.statusCode !== 201) console.error('Error uploading file: ', result.statusCode); 147 if (result && result.statusCode !== 201) return callback('Error uploading file: ', result.statusCode);
133 if (error) console.error(error); 148 if (error) return callback(error);
134 149
135 app.uploadStatus.done += 1; 150 app.uploadStatus.done += 1;
136 app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.count * 100); 151 app.uploadStatus.percentDone = Math.round(app.uploadStatus.done / app.uploadStatus.count * 100);
137 152
138 if (app.uploadStatus.done >= app.uploadStatus.count) { 153 callback();
139 app.uploadStatus = {
140 busy: false,
141 count: 0,
142 done: 0,
143 percentDone: 100
144 };
145
146 refresh();
147 }
148 }); 154 });
149 } 155 }, function (error) {
156 if (error) console.error(error);
150 157
151 for(var i = 0; i < app.uploadStatus.count; ++i) { 158 app.uploadStatus.busy = false;
152 uploadFile(files[i]); 159 app.uploadStatus.count = 0;
153 } 160 app.uploadStatus.done = 0;
161 app.uploadStatus.percentDone = 100;
162
163 refresh();
164 });
154} 165}
155 166
156function dragOver(event) { 167function dragOver(event) {