From 7415c02ecfe21eff80074605b93fd3354475e7b3 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Sat, 24 Oct 2009 15:09:23 -0400
Subject: [PATCH] - Fix quota indicator issues by content generation on client-size   instead of bin/quotaimage.php: better performance, better styling posibilities (#1486197, #1486220)

---
 CHANGELOG                         |    1 
 /dev/null                         |  204 ----------------------------------
 skins/default/templates/mail.html |    2 
 skins/default/mail.css            |   17 ++
 program/steps/mail/func.inc       |   65 ++++------
 program/js/app.js                 |   64 ++++++++++
 6 files changed, 105 insertions(+), 248 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 077b2a0..e392985 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fix quota indicator issues by content generation on client-size (#1486197, #1486220)
 - Don't display disabled sections in Settings (#1486099)
 - Added server-side e-mail address validation with 'email_dns_check' option (#1485857)
 - Fix login page loading into an iframe when session expires (#1485952)
diff --git a/bin/quotaimg.php b/bin/quotaimg.php
deleted file mode 100644
index 817d385..0000000
--- a/bin/quotaimg.php
+++ /dev/null
@@ -1,204 +0,0 @@
-<?php
-/*
- +-----------------------------------------------------------------------+
- | bin/quotaimg.php                                                      |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- | PURPOSE:                                                              |
- |   Create a GIF image showing the mailbox quot as bar                  |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Brett Patterson <brett2@umbc.edu>                             |
- +-----------------------------------------------------------------------+
-
- $Id$
-
-*/
-
-define('INSTALL_PATH', realpath(dirname(__FILE__).'/..') . '/');
-require INSTALL_PATH . 'program/include/iniset.php';
-
-$RCMAIL = rcmail::get_instance();
-
-$used   = isset($_GET['u']) ? intval($_GET['u']) : '??';
-$quota  = isset($_GET['q']) ? intval($_GET['q']) : '??';
-$width  = empty($_GET['w']) ? 100 : min(300, intval($_GET['w']));
-$height = empty($_GET['h']) ? 14  : min(50,  intval($_GET['h']));
-
-/**
- * Quota display
- * 
- *	Modify the following few elements to change the display of the image.
- *	Modifiable attributes are:
- *	bool	border	::	Defines whether you want to show a border around it?
- *	bool	unknown	::	Leave default; Defines whether quota is "unknown"
- *
- *	int		height	::	Defines height of the image
- *	int		width	::	Defines width of the image
- *	int		font	::	Changes the font size & font used in the GD library.
- *						Available values are from 1 to 5.
- *	int		padding	::	Changes the offset (in pixels) from the top of the image
- *                      to where the top of the text will be aligned. User
- *                      greater than 0 to ensure text is off the border.
- *	array	limit	::	Holds the integer values of in an associative array as
- *                      to what defines the upper and lower levels for quota
- *                      display.
- *						High - Quota is nearing capacity.
- *						Mid  - Quota is around the middle
- *						Low  - Currently not used.
- *	array	color	::	An associative array of strings of comma separated
- *                      values (R,G,B) for use in color creation.  Define the
- *                      RGB values you'd like to use. A list of colors (and
- *                      their RGB values) can be found here:
- *						http://www.december.com/html/spec/colorcodes.html
- * 
- * @return void
- * 
- * @param mixed $used   The amount used, or ?? if unknown.
- * @param mixed $total  The total available, or ?? if unknown.
- * @param int   $width  Width of the image.
- * @param int   $height Height of the image.
- * 
- * @see rcube_imap::get_quota()
- * @see iil_C_GetQuota()
- * 
- * @todo Make colors a config option.
- */
-function genQuota($used, $total, $width, $height)
-{
-	$unknown = false;
-	$border  = 0;
-
-	$font    = 2;
-	$padding = 0;
-
-	$limit['high'] = 80;
-	$limit['mid']  = 55;
-	$limit['low']  = 0;
-
-	// Fill Colors
-	$color['fill']['high'] = '243, 49, 49';	  // Near quota fill color
-	$color['fill']['mid']  = '245, 173, 60'; // Mid-area of quota fill color
-	$color['fill']['low']  = '145, 225, 100'; // Far from quota fill color
-
-	// Background colors
-	$color['bg']['OL']      = '215, 13, 13';   // Over limit bbackground
-	$color['bg']['Unknown'] = '238, 99, 99';   // Unknown background
-	$color['bg']['quota']   = '255, 255, 255'; // Normal quota background
-
-	// Misc. Colors
-	$color['border'] = '0, 0, 0';
-	$color['text']['high'] = '255, 255, 255';  // white text for red background
-	$color['text']['mid'] = '102, 102, 102';
-	$color['text']['low'] = '102, 102, 102';
-	$color['text']['normal'] = '102, 102, 102';
-
-
-	/************************************
-	 *****	DO NOT EDIT BELOW HERE	*****
-	 ***********************************/
-
-	// @todo: Set to "??" instead?
-	if (preg_match('/^[^0-9?]*$/', $used) || preg_match('/^[^0-9?]*$/', $total)) {
-		return false; 
-	}
-
-	if (strpos($used, '?') !== false || strpos($total, '?') !== false && $used != 0) {
-		$unknown = true; 
-	}
-
-	$im = imagecreate($width, $height);
-
-	if ($border) {
-		list($r, $g, $b) = explode(',', $color['border']);
-        
-		$borderc = imagecolorallocate($im, $r, $g, $b);
-        
-		imageline($im, 0, 0, $width, 0, $borderc);
-		imageline($im, 0, $height-$border, 0, 0, $borderc);
-		imageline($im, $width-1, 0, $width-$border, $height, $borderc);
-		imageline($im, $width, $height-$border, 0, $height-$border, $borderc);
-	}
-		
-	if ($unknown) {
-		list($r, $g, $b) = explode(',', $color['text']['normal']);
-		$text = imagecolorallocate($im, $r, $g, $b);
-		list($r, $g, $b) = explode(',', $color['bg']['Unknown']);
-		$background = imagecolorallocate($im, $r, $g, $b);
-
-		imagefilledrectangle($im, 0, 0, $width, $height, $background);
-
-		$string = 'Unknown';
-		$mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
-		imagestring($im, $font, $mid, $padding, $string, $text);
-	} else if ($used > $total) {
-		list($r, $g, $b) = explode(',', $color['text']['normal']);
-		$text = imagecolorallocate($im, $r, $g, $b);
-		list($r, $g, $b) = explode(',', $color['bg']['OL']);
-		$background = imagecolorallocate($im, $r, $g, $b);
-        
-		imagefilledrectangle($im, 0, 0, $width, $height, $background);
-
-		$string = 'Over Limit';
-		$mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
-		imagestring($im, $font, $mid, $padding, $string, $text);
-	} else {
-		list($r, $g, $b) = explode(',', $color['bg']['quota']);
-		$background = imagecolorallocate($im, $r, $b, $g);
-        
-		imagefilledrectangle($im, 0, 0, $width, $height, $background);
-		
-		$quota = ($used==0)?0:(round($used/$total, 2)*100);
-
-		if ($quota >= $limit['high']) {
-			list($r, $g, $b) = explode(',', $color['text']['high']);
-			$text = imagecolorallocate($im, $r, $g, $b);
-			list($r, $g, $b) = explode(',', $color['fill']['high']);
-			$fill = imagecolorallocate($im, $r, $g, $b);
-		} elseif($quota >= $limit['mid']) {
-			list($r, $g, $b) = explode(',', $color['text']['mid']);
-			$text = imagecolorallocate($im, $r, $g, $b);
-			list($r, $g, $b) = explode(',', $color['fill']['mid']);
-			$fill = imagecolorallocate($im, $r, $g, $b);
-		} else {
-			// if($quota >= $limit['low'])
-			list($r, $g, $b) = explode(',', $color['text']['low']);
-			$text = imagecolorallocate($im, $r, $g, $b);
-			list($r, $g, $b) = explode(',', $color['fill']['low']);
-			$fill = imagecolorallocate($im, $r, $g, $b);
-		}
-
-		$quota_width = $quota / 100 * $width;
-		if ($quota_width)
-			imagefilledrectangle($im, $border, 0, $quota_width, $height-2*$border, $fill);
-
-		$string = $quota . '%';
-		$mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
-		// Print percent in black
-		imagestring($im, $font, $mid, $padding, $string, $text); 
-	}
-
-	header('Content-Type: image/gif');
-
-	// cache for 1 hour
-	$maxage = 3600;
-	header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$maxage). ' GMT');
-	header('Cache-Control: max-age=' . $maxage);
-	
-	imagegif($im);
-	imagedestroy($im);
-}
-
-if (!empty($RCMAIL->user->ID) && $width > 1 && $height > 1) {
-	genQuota($used, $quota, $width, $height);
-}
-else {
-	header("HTTP/1.0 403 Forbidden");
-	echo "Requires a valid user session and positive values";
-}
-
-exit;
-?>
diff --git a/program/js/app.js b/program/js/app.js
index f98cf5f..83162a9 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -3914,8 +3914,12 @@
   // replace content of quota display
   this.set_quota = function(content)
     {
-    if (content && this.gui_objects.quotadisplay)
-      $(this.gui_objects.quotadisplay).html(content);
+    if (content && this.gui_objects.quotadisplay) {
+      if (typeof(content) == 'object')
+        this.percent_indicator(this.gui_objects.quotadisplay, content);
+      else
+        $(this.gui_objects.quotadisplay).html(content);
+      }
     };
 
   // update the mailboxlist
@@ -4044,6 +4048,61 @@
     elem.onclick = function() { rcmail.load_headers(elem); }
     }
 
+  // percent (quota) indicator
+  this.percent_indicator = function(obj, data)
+    {
+    if (!data || !obj)
+      return false;
+
+    var limit_high = 80;
+    var limit_mid  = 55;
+    var width = data.width ? data.width : this.env.indicator_width ? this.env.indicator_width : 100;
+    var height = data.height ? data.height : this.env.indicator_height ? this.env.indicator_height : 24;
+    var quota = data.percent ? Math.abs(parseInt(data.percent)) : 0;
+    var quota_width = parseInt(quota / 100 * width);
+    var pos = $(obj).position();
+
+    this.env.indicator_width = width;
+    this.env.indicator_height = height;
+    
+    // overlimit
+    if (quota_width > width) {
+      quota_width = width;
+      quota = 100; 
+      }
+  
+    // main div
+    var main = $('<div>');
+    main.css({position: 'absolute', top: pos.top, left: pos.left,
+	width: width + 'px', height: height + 'px', zIndex: 100, lineHeight: height + 'px'})
+	.attr('title', data.title).addClass('quota_text').html(quota + '%');
+    // used bar
+    var bar1 = $('<div>');
+    bar1.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
+	width: quota_width + 'px', height: height + 'px', zIndex: 99});
+    // background
+    var bar2 = $('<div>');
+    bar2.css({position: 'absolute', top: pos.top + 1, left: pos.left + 1,
+	width: width + 'px', height: height + 'px', zIndex: 98})
+	.addClass('quota_bg');
+
+    if (quota >= limit_high) {
+      main.addClass(' quota_text_high');
+      bar1.addClass('quota_high');
+      }
+    else if(quota >= limit_mid) {
+      main.addClass(' quota_text_mid');
+      bar1.addClass('quota_mid');
+      }
+    else {
+      main.addClass(' quota_text_normal');
+      bar1.addClass('quota_low');
+      }
+
+    // replace quota image
+    obj.innerHTML = '';
+    $(obj).append(bar1).append(bar2).append(main);
+    }
 
   /********************************************************/
   /*********  html to text conversion functions   *********/
@@ -4326,4 +4385,3 @@
 rcube_webmail.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
 rcube_webmail.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
 rcube_webmail.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
-
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 445b89d..b137967 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -517,8 +517,16 @@
     $_SESSION['quota_display'] = $attrib['display'];
 
   $OUTPUT->add_gui_object('quotadisplay', $attrib['id']);
-
-  return html::span($attrib, rcmail_quota_content(NULL, $attrib));
+  
+  $quota = rcmail_quota_content(NULL, $attrib);
+  
+  if (is_array($quota)) {
+    $OUTPUT->add_script('$(document).ready(function(){
+	rcmail.set_quota('.json_serialize($quota).')});', 'foot');
+    $quota = '';
+    }
+  
+  return html::span($attrib, $quota);
   }
 
 
@@ -528,49 +536,34 @@
 
   $display = isset($_SESSION['quota_display']) ? $_SESSION['quota_display'] : '';
 
-  if (is_array($quota) && !empty($quota['used']) && !empty($quota['total']))
-    {
-      if (!isset($quota['percent']))
-        $quota['percent'] = $quota['used'] / $quota['total'];
+  if (empty($quota)) {
+    if (!$IMAP->get_capability('QUOTA'))
+      return rcube_label('unknown');
+    else 
+      $quota = $IMAP->get_quota();
     }
-  elseif (!$IMAP->get_capability('QUOTA'))
-    return rcube_label('unknown');
-  else
-    $quota = $IMAP->get_quota();
 
   if ($quota && !($quota['total']==0 && $RCMAIL->config->get('quota_zero_as_unlimited')))
     {
-    $quota_text = sprintf('%s / %s (%.0f%%)',
-                          show_bytes($quota['used'] * 1024),
-                          show_bytes($quota['total'] * 1024),
-                          $quota['percent']);
+    $quota_result = sprintf('%s / %s (%.0f%%)',
+        show_bytes($quota['used'] * 1024), show_bytes($quota['total'] * 1024),
+        $quota['percent']);
 
-    // show quota as image (by Brett Patterson)
-    if ($display == 'image' && function_exists('imagegif'))
-      {
-      if (!$attrib['width'])
-        $attrib['width'] = isset($_SESSION['quota_width']) ? $_SESSION['quota_width'] : 100;
-      else
-	$_SESSION['quota_width'] = $attrib['width'];
-
-      if (!$attrib['height'])
-        $attrib['height'] = isset($_SESSION['quota_height']) ? $_SESSION['quota_height'] : 14;
-      else
-	$_SESSION['quota_height'] = $attrib['height'];
-	    
-      $quota_text = sprintf('<img src="./bin/quotaimg.php?u=%s&amp;q=%d&amp;w=%d&amp;h=%d" width="%d" height="%d" alt="%s" title="%s / %s" />',
-                            $quota['used'], $quota['total'],
-                            $attrib['width'], $attrib['height'],
-                            $attrib['width'], $attrib['height'],
-                            $quota_text,
-                            show_bytes($quota['used'] * 1024),
-                            show_bytes($quota['total'] * 1024));
+    if ($display == 'image') {
+      $quota_result = array(	    
+    	'percent' 	=> $quota['percent'],
+        'title'		=> $quota_result,
+	);
+      if ($attrib['width'])
+        $quota_result['width'] = $attrib['width'];
+      if ($attrib['height'])
+        $quota_result['height']	= $attrib['height'];
       }
     }
   else
-    $quota_text = rcube_label('unlimited');
+    return rcube_label('unlimited');
 
-  return $quota_text;
+  return $quota_result;
   }
 
 
diff --git a/skins/default/mail.css b/skins/default/mail.css
index 31d7c61..f9777ee 100644
--- a/skins/default/mail.css
+++ b/skins/default/mail.css
@@ -839,12 +839,21 @@
   color: #CCCCCC;
 }
 
-#quotadisplay img
-{
-  margin-left: 4px;
+.quota_text {
+  text-align: center;
+  font-size: 10px;
+  color: #666;
   border: 1px solid #999;
+  cursor: default;
 }
-
+.quota_bg { background-color: white; }
+.quota_high { background-color: #F33131; }
+.quota_mid { background-color: #F5AD3C; }
+.quota_low { background-color: #91E164; }
+.quota_text_high { color: white; }
+.quota_text_mid { color: #666; }
+.quota_text_low { color: #666; }
+	  
 
 /** message view styles */
 
diff --git a/skins/default/templates/mail.html b/skins/default/templates/mail.html
index ed19ff9..db2f4fe 100644
--- a/skins/default/templates/mail.html
+++ b/skins/default/templates/mail.html
@@ -84,7 +84,7 @@
       <roundcube:button command="select-none" type="link" title="none" class="buttonPas none" classAct="button none" classSel="button nonesel" content=" " />
       <roundcube:container name="listcontrols" id="listcontrols" />
   <roundcube:if condition="env:quota" />
-  <span style="margin-left: 20px"><roundcube:label name="quota" />:</span>
+  <span style="margin-left: 20px; margin-right: 5px"><roundcube:label name="quota" />:</span>
   <roundcube:object name="quotaDisplay" display="image" width="100" height="14" id="quotadisplay" />
   <roundcube:endif />
 </div>

--
Gitblit v1.9.1