Преглед на файлове

Improves the Javascript handling files upload

What has been added:
- per file progress bar
- per file upload cancel
- drag and drop of files and folders (Chrome) is back
- file paste (Chrome)

And some CSS improvement regarding failed and done file transfert.

Signed-off-by: Felix Paul Kühne <fkuehne@videolan.org>
Jean-Romain Prévost преди 12 години
родител
ревизия
98befac611
променени са 3 файла, в които са добавени 127 реда и са изтрити 73 реда
  1. 2 43
      Resources/web/index.html
  2. 69 0
      Resources/web/main.js
  3. 56 30
      Resources/web/style.css

+ 2 - 43
Resources/web/index.html

@@ -8,25 +8,7 @@
     <script type="text/javascript" src="jquery.ui.widget.js"></script>
     <script type="text/javascript" src="jquery.iframe-transport.js"></script>
     <script type="text/javascript" src="jquery.fileupload.js"></script>
-    <script>
-      $(function(){
-        $('#fileupload').fileupload({
-          dataType: 'json',
-          done: function (e, data) {
-            $('#progress').hide();
-            $.each(data.files, function (index, file) {
-              $('<li/>').text(file.name).appendTo($('#uploads ul'));
-            });
-            $('#uploads').show();
-          },
-          progressall: function (e, data) {
-            $('#progress').show();
-            var progress = parseInt(data.loaded / data.total * 100, 10);
-            $('#progress .bar').css('width', progress + '%');
-          }
-        });
-      });
-    </script>
+    <script type="text/javascript" src="main.js"></script>
   </head>
   <body>
     <header>
@@ -39,31 +21,8 @@
       </nav>
     </header>
     <div class="main">
-
-      <div id="progress" style="display: none;">
-        <div class="bar" style="width: 50%;"></div>
-      </div>
-      
-      <div id="uploads" style="display: none;">
-        <p>So far you have uploaded:</p>
-        <ul></ul>
-      </div>
-
       <section class="uploads">
-        <ul>
-          <li>
-            <div class="filename">Game of Thrones S02E01 720p HDTV.DD5.1 x264-EbP.mkv</div>
-            <div class="progress">
-              <div class="bar" style="width: 2%"></div>
-            </div>
-          </li>
-          <li>
-            <div class="filename">Game of Thrones S02E01 720p HDTV.DD5.1 x264-EbP.mkv</div>
-            <div class="progress">
-              <div class="bar" style="width: 80%"></div>
-            </div>
-          </li>
-        </ul>
+        <ul></ul>
       </section>
 
       <section class="message">

+ 69 - 0
Resources/web/main.js

@@ -0,0 +1,69 @@
+$(function(){
+    $(document).bind('drop dragover', function (e) {
+        e.preventDefault();
+    });
+    $(document).bind('dragover', function () {
+        $('.main').addClass('drop');
+    })
+    $(document).bind('dragexit dragleave dragend drop', function () {
+        $('.main').removeClass('drop');
+    })
+
+    var fileupload = $('#fileupload').fileupload({
+        dataType: 'json',
+        url: 'upload.json',
+        dropZone: $(document),
+        pasteZone: $(document),
+        add: add
+    });
+
+    fileupload.bind('fileuploaddone', done);
+    fileupload.bind('fileuploadfail', fail);
+    fileupload.bind('fileuploadprogress', progress);
+
+    var xhrCache = [];
+    function add (e, data) {
+        $('.message').hide();
+        var xhr = data.submit();
+        $.each(data.files, function(index, file){
+            file._ID = xhrCache.length;
+            xhrCache[file._ID] = xhr;
+            var html = '<li data-file-id="' + file._ID + '">';
+            html += '<div class="filename">' + file.name + '</div>';
+            html += '<div class="progress"><div class="bar" style="width: 0%"></div></div>';
+            html += '<div class="stop"></div>';
+            html += '</li>';
+            var tmpl = $(html);
+            $('.uploads ul').append(html);
+        });
+    }
+
+    function done (e, data) {
+        $.each(data.files, function (index, file) {
+            $('li[data-file-id=' + file._ID + ']').addClass('done');
+        });
+    }
+
+    function progress (e, data) {
+        var prog = Math.ceil(data.loaded / data.total * 100) + '%';
+        $.each(data.files, function (index, file) {
+            $('li[data-file-id=' + file._ID + '] .progress .bar').css('width', prog);
+        });
+    }
+
+    function fail (e, data) {
+        console.log('File transfer failed', data.errorThrown, data.textStatus);
+        $.each(data.files, function (index, file) {
+            $('li[data-file-id=' + file._ID + ']').addClass('fail');
+        });
+    }
+
+    $('.uploads').delegate('.stop', 'click', stopTransfer);
+
+    function stopTransfer (e) {
+        var li = $(e.currentTarget).parent('li');
+        var id = li.data('file-id');
+        xhrCache[id].abort();
+        li.addClass('fail');
+    }
+});

+ 56 - 30
Resources/web/style.css

@@ -25,7 +25,7 @@ body {
 }
 
 div.main {
-  border: 2px solid inherit;
+  border: 2px solid transparent;
   position: absolute;
   top: 88px;
   bottom: 0;
@@ -119,32 +119,6 @@ nav {
   cursor: pointer;
 }
 
-
-#progress {
-  width: 100%;
-  background-color: red;
-  border-radius: 5px;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(170, 170, 170)), to(rgb(200, 200, 200)));
-  background-image: -webkit-linear-gradient(top, rgb(170, 170, 170), rgb(200, 200, 200));
-  background-image: -moz-linear-gradient(top, rgb(170, 170, 170), rgb(200, 200, 200));
-  background-image: -ms-linear-gradient(top, rgb(170, 170, 170), rgb(200, 200, 200));
-  background-image: -o-linear-gradient(top, rgb(170, 170, 170), rgb(200, 200, 200));
-  background-image: linear-gradient(top, rgb(170, 170, 170), rgb(200, 200, 200));
-}
-
-#progress .bar {
-  border-radius: 5px;
-  height: 18px;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(234, 171, 103)), to(rgb(214, 112, 0)));
-  background-image: -webkit-linear-gradient(top, rgb(234, 171, 103), rgb(214, 112, 0));
-  background-image: -moz-linear-gradient(top, rgb(234, 171, 103), rgb(214, 112, 0));
-  background-image: -ms-linear-gradient(top, rgb(234, 171, 103), rgb(214, 112, 0));
-  background-image: -o-linear-gradient(top, rgb(234, 171, 103), rgb(214, 112, 0));
-  background-image: linear-gradient(top, rgb(234, 171, 103), rgb(214, 112, 0));
-}
-
-form,#uploads {}
-
 .message {
   margin: 100px 0px;
 }
@@ -160,12 +134,10 @@ form,#uploads {}
   text-shadow: 1px 1px 2px black;
 }
 
-.uploads {
-  
-}
 .uploads li {
   height: 80px;
   padding: 0 20px;
+  position: relative;
 }
 .uploads li:nth-child(2n) {
   background-color: rgba(0,0,0,0.2);
@@ -201,9 +173,63 @@ form,#uploads {}
   box-shadow: inset 0px 3px 0px -1px #e09d54, 0px 3px 0px -1px rgba(255,255,255,0.1);
 }
 
+.uploads li.fail .progress .bar {
+  background-image: none;
+  background-color: transparent;
+  box-shadow: none;
+}
+
+.uploads li.fail .progress:before,
+.uploads li.done .progress .bar:before {
+  line-height: 12px;
+  font-size: 13px;
+  font-weight: bold;
+  padding: 0 12px;
+  float: right;
+}
+.uploads li.fail .progress:before {
+  content: "File transfer failed";
+  color: #c95a07;
+}
+.uploads li.done .progress .bar:before {
+  content: "File transfer complete";
+  color: white;
+}
+.uploads li:hover .stop {
+  display: block;
+}
+.uploads li.done:hover .stop,
+.uploads li.fail:hover .stop {
+  display: none;
+}
+.uploads .stop {
+  border: 3px solid white;
+  width: 26px;
+  height: 26px;
+  border-radius: 50%;
+  background-color: #bd1421;
+  
+  position: absolute;
+  top: 8px;
+  right: 8px;
+  
+  box-shadow: inset 3px 10px 4px -4px rgba(255,255,255,0.3);
+  cursor: pointer;
+  display: none;
+}
+.uploads .stop:before {
+  content: "-";
+  font-size: 46px;
+  line-height: 12px;
+  text-align: center;
+  width: 100%;
+  padding: 1px;
+}
+
 footer {
   font-size: .9em;
   line-height: 1.3em;
+  margin-top: 40px;
   padding-bottom: 8px; 
   text-align: center;
   color: rgb(120, 120, 120);