From ebf8726eeaa507096ef28e776303b459c401a924 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Sat, 03 Oct 2009 15:12:27 -0400
Subject: [PATCH] - Added attachment upload indicator with parallel upload (#1486058)

---
 CHANGELOG                                                 |    1 
 plugins/filesystem_attachments/filesystem_attachments.php |   11 ++++-
 program/steps/mail/attachments.inc                        |    7 ++-
 program/steps/mail/compose.inc                            |    4 +
 skins/default/mail.css                                    |    2 
 program/localization/en_US/messages.inc                   |    1 
 program/localization/pl_PL/messages.inc                   |    1 
 skins/default/templates/compose.html                      |    2 
 program/js/app.js                                         |   59 ++++++++++++++++++++++++++---
 9 files changed, 74 insertions(+), 14 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 6a84497..b051833 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Added attachment upload indicator with parallel upload (#1486058)
 - Use default_charset for bodies of messages without charset definition (#1486187)
 - Password: added cPanel driver
 - Fix return to first page from e-mail screen (#1486105)
diff --git a/plugins/filesystem_attachments/filesystem_attachments.php b/plugins/filesystem_attachments/filesystem_attachments.php
index fcdcea7..dce2de2 100644
--- a/plugins/filesystem_attachments/filesystem_attachments.php
+++ b/plugins/filesystem_attachments/filesystem_attachments.php
@@ -57,7 +57,7 @@
         $tmpfname = tempnam($temp_dir, 'rcmAttmnt');
 
         if (move_uploaded_file($args['path'], $tmpfname) && file_exists($tmpfname)) {
-            $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+            $args['id'] = $this->file_id();
             $args['path'] = $tmpfname;
             $args['status'] = true;
 
@@ -88,7 +88,7 @@
                 return $args;
         }
         
-        $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+        $args['id'] = $this->file_id();
         $args['status'] = true;
             
         // Note the file for later cleanup
@@ -146,4 +146,11 @@
         }
         return $args;
     }
+
+    function file_id()
+    {
+        $userid = rcmail::get_instance()->user->ID;
+	list($usec, $sec) = explode(' ', microtime()); 
+        return preg_replace('/[^0-9]/', '', $userid . $sec . $usec);
+    }
 }
diff --git a/program/js/app.js b/program/js/app.js
index 91d0f13..643664a 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -1629,15 +1629,15 @@
     // also send search request to get the right messages
     if (this.env.search_request)
       add_url += '&_search='+this.env.search_request;
-
+      
     // set page=1 if changeing to another mailbox
-    if (!page && this.env.mailbox != mbox)
+    if (!page)
       {
       page = 1;
       this.env.current_page = page;
       this.show_contentframe(false);
       }
-
+    
     if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
       add_url += '&_refresh=1';
 
@@ -2171,6 +2171,14 @@
       return false;
       }
 
+    // check if all files has been uploaded
+    if (this.gui_objects.attachmentlist) {
+      var list = this.gui_objects.attachmentlist.getElementsByTagName("li");
+      for (i=0;i<list.length;i++)
+        if (!String(list[i].id).match(/^rcmfile/))
+          return false;
+    }
+    
     // display localized warning for missing subject
     if (input_subject.val() == '')
       {
@@ -2450,10 +2458,38 @@
         document.body.appendChild(frame);
         }
 
+      // handle upload errors, parsing iframe content in onload
+      var fr = document.getElementsByName(frame_name)[0];
+      $(fr).bind('load', {ts:ts}, function(e) {
+	var content = '';
+        try {
+          if (this.contentDocument) {
+	    var d = this.contentDocument;
+	  } else if (this.contentWindow) {
+	    var d = this.contentWindow.document;
+	  }
+	  content = d.childNodes[0].innerHTML;
+        } catch (e) {}
+
+	if (!content.match(/add2attachment/)) {
+	alert(content)
+	  rcmail.display_message(rcmail.get_label('fileuploaderror'), 'error');
+	  rcmail.remove_from_attachment_list(e.data.ts);
+        }
+      });
+
       form.target = frame_name;
-      form.action = this.env.comm_path+'&_action=upload';
+      form.action = this.env.comm_path+'&_action=upload&_uploadid='+ts;
       form.setAttribute('enctype', 'multipart/form-data');
       form.submit();
+      
+      // hide upload form
+      this.show_attachment_form(false);
+      // display upload indicator
+      var content = this.get_label('uploading');
+      if (this.env.loadingicon)
+        content = '<img src="'+this.env.loadingicon+'" alt="" />'+content;
+      this.add2attachment_list(ts, content);
       }
     
     // set reference to the form object
@@ -2463,12 +2499,21 @@
 
   // add file name to attachment list
   // called from upload page
-  this.add2attachment_list = function(name, content)
+  this.add2attachment_list = function(name, content, upload_id)
     {
     if (!this.gui_objects.attachmentlist)
       return false;
-      
-    $('<li>').attr('id', name).html(content).appendTo(this.gui_objects.attachmentlist);
+    
+    var indicator;
+    // replace indicator's li
+    if (upload_id && (indicator = document.getElementById(upload_id))) {
+      var li = document.createElement('li');
+      $(li).attr('id', name).html(content);
+      indicator.parentNode.replaceChild(li, indicator);
+      } else { // add new li
+      $('<li>').attr('id', name).html(content).appendTo(this.gui_objects.attachmentlist);
+      }
+    
     return true;
     };
 
diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc
index a9d2d67..3bc5132 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -28,6 +28,7 @@
 $messages['loggedout'] = 'You have successfully terminated the session. Good bye!';
 $messages['mailboxempty'] = 'Mailbox is empty';
 $messages['loading'] = 'Loading...';
+$messages['uploading'] = 'Uploading file...';
 $messages['loadingdata'] = 'Loading data...';
 $messages['checkingmail'] = 'Checking for new messages...';
 $messages['sendingmessage'] = 'Sending message...';
diff --git a/program/localization/pl_PL/messages.inc b/program/localization/pl_PL/messages.inc
index 0c0168f..69b9b42 100644
--- a/program/localization/pl_PL/messages.inc
+++ b/program/localization/pl_PL/messages.inc
@@ -32,6 +32,7 @@
 $messages['loggedout'] = 'Użytkownik wylogował się poprawnie.';
 $messages['mailboxempty'] = 'Skrzynka jest pusta!';
 $messages['loading'] = 'Ładowanie...';
+$messages['uploading'] = 'Zapisywanie pliku...';
 $messages['loadingdata'] = 'Ładowanie danych...';
 $messages['checkingmail'] = 'Sprawdzanie nowych wiadomości...';
 $messages['sendingmessage'] = 'Wysyłanie wiadomości...';
diff --git a/program/steps/mail/attachments.inc b/program/steps/mail/attachments.inc
index b57037d..28d6108 100644
--- a/program/steps/mail/attachments.inc
+++ b/program/steps/mail/attachments.inc
@@ -74,6 +74,8 @@
 // clear all stored output properties (like scripts and env vars)
 $OUTPUT->reset();
 
+$uploadid = get_input_value('_uploadid', RCUBE_INPUT_GET);
+
 if (is_array($_FILES['_attachments']['tmp_name'])) {
   foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
     $attachment = array(
@@ -109,7 +111,7 @@
 
       $content .= Q($attachment['name']);
       
-      $OUTPUT->command('add2attachment_list', "rcmfile$id", $content);
+      $OUTPUT->command('add2attachment_list', "rcmfile$id", $content, $uploadid);
     }
     else {  // upload failed
       $err = $_FILES['_attachments']['error'][$i];
@@ -124,6 +126,7 @@
       }
     
       $OUTPUT->command('display_message', $msg, 'error');
+      $OUTPUT->command('remove_from_attachment_list', $uploadid);
     }
   }
 }
@@ -135,10 +138,10 @@
   else
     $msg = rcube_label('fileuploaderror');
   $OUTPUT->command('display_message', $msg, 'error');
+  $OUTPUT->command('remove_from_attachment_list', $uploadid);
 }
 
 // send html page with JS calls as response
-$OUTPUT->command('show_attachment_form', false);
 $OUTPUT->command('auto_save_start', false);
 $OUTPUT->send('iframe');
 
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index 4a03cd7..e3c7fda 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -94,7 +94,7 @@
 // add some labels to client
 $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning',
     'nobodywarning', 'notsentwarning', 'savingmessage', 'sendingmessage', 'messagesaved',
-    'converting', 'editorwarning', 'searching');
+    'converting', 'editorwarning', 'searching', 'uploading', 'fileuploaderror');
 
 // add config parameters to client script
 if (!empty($CONFIG['drafts_mbox'])) {
@@ -809,6 +809,8 @@
 
   if ($attrib['deleteicon'])
     $_SESSION['compose']['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon'];
+  if ($attrib['loadingicon'])
+    $OUTPUT->set_env('loadingicon', $CONFIG['skin_path'] . $attrib['loadingicon']);
 
   $OUTPUT->add_gui_object('attachmentlist', $attrib['id']);
     
diff --git a/skins/default/mail.css b/skins/default/mail.css
index f63c3f2..05b2a85 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -1238,7 +1238,7 @@
   position: absolute;
   top: 100px;
   left: 20px;
-  width: 170px;
+  width: 175px;
 }
 
 #compose-attachments ul
diff --git a/skins/default/templates/compose.html b/skins/default/templates/compose.html
index 12d5e94..6441332 100644
--- a/skins/default/templates/compose.html
+++ b/skins/default/templates/compose.html
@@ -93,7 +93,7 @@
 
 <div id="compose-attachments">
 <div id="attachment-title"><roundcube:label name="attachments" /></div>
-<roundcube:object name="composeAttachmentList" deleteIcon="/images/icons/delete.png" />
+<roundcube:object name="composeAttachmentList" deleteIcon="/images/icons/delete.png" loadingIcon="/images/display/loading_blue.gif" />
 <p><roundcube:button command="add-attachment" imagePas="/images/buttons/add_pas.png" imageSel="/images/buttons/add_sel.png" imageAct="/images/buttons/add_act.png" width="23" height="18" title="addattachment" /></p>
 </div>
 

--
Gitblit v1.9.1