summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2014-09-08 16:56:23 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2014-09-08 16:56:23 (GMT)
commitdc335c4d26713a1f6e18b263e26540d28df58aa2 (patch)
tree8923b375345967cf917646970020d13d506bcb5f
parent7e6056770ee6c28f33f3f04dead92d5a689deaa0 (diff)
downloadroundcubemail-plugins-kolab-dc335c4d26713a1f6e18b263e26540d28df58aa2.tar.gz
Refine virtual user folders handling in new folder navigation according to #3378
-rw-r--r--plugins/calendar/drivers/kolab/kolab_driver.php10
-rw-r--r--plugins/calendar/drivers/kolab/kolab_user_calendar.php14
-rw-r--r--plugins/calendar/lib/calendar_ui.php2
-rw-r--r--plugins/calendar/skins/larry/calendar.css5
-rw-r--r--plugins/calendar/skins/larry/images/calendars.pngbin5144 -> 3664 bytes
-rw-r--r--plugins/libkolab/js/folderlist.js71
-rw-r--r--plugins/libkolab/lib/kolab_storage.php10
-rw-r--r--plugins/libkolab/lib/kolab_storage_folder_api.php9
-rw-r--r--plugins/libkolab/lib/kolab_storage_folder_user.php34
9 files changed, 139 insertions, 16 deletions
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index b9eba2d..fec96f4 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -93,10 +93,13 @@ class kolab_driver extends calendar_driver
$this->calendars = array();
foreach ($folders as $folder) {
- if ($folder instanceof kolab_storage_folder_user)
+ if ($folder instanceof kolab_storage_folder_user) {
$calendar = new kolab_user_calendar($folder->name, $this->cal);
- else
+ $calendar->subscriptions = count($folder->children) > 0;
+ }
+ else {
$calendar = new kolab_calendar($folder->name, $this->cal);
+ }
if ($calendar->ready) {
$this->calendars[$calendar->id] = $calendar;
@@ -210,7 +213,7 @@ class kolab_driver extends calendar_driver
}
if ($cal->subscriptions) {
- $calendars[$cal->id]['subscribed'] = (bool)$cal->is_subscribed();
+ $calendars[$cal->id]['subscribed'] = $cal->is_subscribed();
}
}
@@ -488,6 +491,7 @@ class kolab_driver extends calendar_driver
foreach (kolab_storage::list_user_folders($user, 'event', false) as $foldername) {
$cal = new kolab_calendar($foldername, $this->cal);
$this->calendars[$cal->id] = $cal;
+ $calendar->subscriptions = true;
}
}
diff --git a/plugins/calendar/drivers/kolab/kolab_user_calendar.php b/plugins/calendar/drivers/kolab/kolab_user_calendar.php
index 859dc4c..18b1ecc 100644
--- a/plugins/calendar/drivers/kolab/kolab_user_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_user_calendar.php
@@ -51,6 +51,7 @@ class kolab_user_calendar extends kolab_calendar
}
$this->ready = !empty($this->userdata['kolabtargetfolder']);
+ $this->storage->type = 'event';
if ($this->ready) {
// ID is derrived from the user's kolabtargetfolder attribute
@@ -141,6 +142,15 @@ class kolab_user_calendar extends kolab_calendar
return false;
}
+ /**
+ * Check subscription status of this folder
+ *
+ * @return boolean True if subscribed, false if not
+ */
+ public function is_subscribed()
+ {
+ return $this->storage->is_subscribed();
+ }
/**
* Update properties of this calendar folder
@@ -201,7 +211,7 @@ class kolab_user_calendar extends kolab_calendar
// aggregate all calendar folders the user shares (but are not subscribed)
foreach (kolab_storage::list_user_folders($this->userdata, 'event', false) as $foldername) {
- if (!kolab_storage::folder_is_subscribed($foldername, true)) {
+ if (!empty($_REQUEST['_quickview']) || !kolab_storage::folder_is_subscribed($foldername, true)) {
$cal = new kolab_calendar($foldername, $this->cal);
foreach ($cal->list_events($start, $end, $search, 1) as $event) {
$this->events[$event['id']] = $event;
@@ -302,7 +312,7 @@ class kolab_user_calendar extends kolab_calendar
'id' => md5($this->id . $from->format('U') . '/' . $to->format('U')),
'calendar' => $this->id,
'changed' => $fb['created'] ?: new DateTime(),
- 'title' => $titlemap[$type] ?: $type,
+ 'title' => $this->get_name() . ' ' . ($titlemap[$type] ?: $type),
'start' => $from,
'end' => $to,
'free_busy' => $statusmap[$type] ?: 'busy',
diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php
index e66e5f8..2693642 100644
--- a/plugins/calendar/lib/calendar_ui.php
+++ b/plugins/calendar/lib/calendar_ui.php
@@ -298,6 +298,8 @@ class calendar_ui
$classes[] = 'readonly';
if ($prop['subscribed'])
$classes[] = 'subscribed';
+ if ($prop['subscribed'] === 2)
+ $classes[] = 'partial';
if ($prop['class'])
$classes[] = $prop['class'];
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index 17efff5..c6a17c1 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -289,6 +289,11 @@ pre {
background-position: -16px -110px;
}
+#calendars .treelist div.subscribed.partial a.subscribed,
+#calendars .treelist div.subscribed.partial a.subscribed:focus {
+ background-position: -16px -148px;
+}
+
#calendars .treelist li a.quickview {
display: inline-block;
position: absolute;
diff --git a/plugins/calendar/skins/larry/images/calendars.png b/plugins/calendar/skins/larry/images/calendars.png
index 5e53cb6..88eba63 100644
--- a/plugins/calendar/skins/larry/images/calendars.png
+++ b/plugins/calendar/skins/larry/images/calendars.png
Binary files differ
diff --git a/plugins/libkolab/js/folderlist.js b/plugins/libkolab/js/folderlist.js
index 1c8ce2f..b583947 100644
--- a/plugins/libkolab/js/folderlist.js
+++ b/plugins/libkolab/js/folderlist.js
@@ -149,7 +149,8 @@ function kolab_folderlist(node, p)
prop = search_results[id],
parent_id = prop.parent || null,
has_children = node.children && node.children.length,
- dom_node = has_children ? li.children().first().clone(true, true) : li.children().first();
+ dom_node = has_children ? li.children().first().clone(true, true) : li.children().first(),
+ childs = [];
// find parent node and insert at the right place
if (parent_id && me.get_node(parent_id)) {
@@ -171,18 +172,58 @@ function kolab_folderlist(node, p)
.removeClass('virtual');
}
else {
+ // copy childs, too
+ if (has_children && prop.group == 'other user') {
+ for (var cid, j=0; j < node.children.length; j++) {
+ if ((cid = node.children[j].id) && search_results[cid]) {
+ childs.push(search_results_widget.get_node(cid));
+ }
+ }
+ }
+
// move this result item to the main list widget
me.insert({
id: id,
classes: [ prop.group || '' ],
virtual: prop.virtual,
html: dom_node,
+ level: node.level,
+ collapsed: true,
+ children: childs
}, parent_id, prop.group);
}
delete prop.html;
prop.active = active;
me.triggerEvent('insert-item', { id: id, data: prop, item: li });
+
+ // register childs, too
+ if (childs.length) {
+ for (var cid, j=0; j < node.children.length; j++) {
+ if ((cid = node.children[j].id) && search_results[cid]) {
+ prop = search_results[cid];
+ delete prop.html;
+ prop.active = false;
+ me.triggerEvent('insert-item', { id: cid, data: prop });
+ }
+ }
+ }
+ }
+
+ // update the given item's parent's (partial) subscription state
+ function parent_subscription_status(li)
+ {
+ var top_li = li.closest(me.container.children('li')),
+ all_childs = $('li > div:not(.treetoggle)', top_li),
+ subscribed = all_childs.filter('.subscribed').length;
+
+ if (subscribed == 0) {
+ top_li.children('div:first').removeClass('subscribed partial');
+ }
+ else {
+ top_li.children('div:first')
+ .addClass('subscribed')[subscribed < all_childs.length ? 'addClass' : 'removeClass']('partial');
+ }
}
// do some magic when search is performed on the widget
@@ -242,21 +283,39 @@ function kolab_folderlist(node, p)
this.container.on('click', 'a.subscribed, span.subscribed', function(e){
var li = $(this).closest('li'),
id = li.attr('id').replace(new RegExp('^'+p.id_prefix), ''),
- div = li.children().first();
+ div = li.children().first(),
+ is_subscribed;
- if (me.is_search())
+ if (me.is_search()) {
id = id.replace(/--xsR$/, '');
+ li = $(me.get_item(id, true));
+ div = $(div).add(li.children().first());
+ }
if (p.id_decode)
id = p.id_decode(id);
div.toggleClass('subscribed');
- $(this).attr('aria-checked', div.hasClass('subscribed') ? 'true' : 'false');
- me.triggerEvent('subscribe', { id: id, subscribed: div.hasClass('subscribed'), item: li });
+ is_subscribed = div.hasClass('subscribed');
+ $(this).attr('aria-checked', is_subscribed ? 'true' : 'false');
+ me.triggerEvent('subscribe', { id: id, subscribed: is_subscribed, item: li });
+
+ // update subscribe state of all 'virtual user' child folders
+ if (li.hasClass('other user')) {
+ $('ul li > div', li).each(function() {
+ $(this)[is_subscribed ? 'addClass' : 'removeClass']('subscribed');
+ $('.subscribed', div).attr('aria-checked', is_subscribed ? 'true' : 'false');
+ });
+ div.removeClass('partial');
+ }
+ // propagate subscription state to parent 'virtual user' folder
+ else if (li.closest('li.other.user').length) {
+ parent_subscription_status(li);
+ }
e.stopPropagation();
return false;
- })
+ });
}
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
index 144655c..4c29a20 100644
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -1534,6 +1534,16 @@ class kolab_storage
$folders[$foldername] = new kolab_storage_folder_user($foldername, $other_ns);
}
}
+
+ // for every (subscribed) user folder, list all (unsubscribed) subfolders
+ foreach ($folders as $userfolder) {
+ foreach ((array)self::list_folders($userfolder->name . $delimiter, '*', $type, false, $folderdata) as $foldername) {
+ if (!$folders[$foldername]) {
+ $folders[$foldername] = new kolab_storage_folder($foldername, $folderdata[$foldername]);
+ $userfolder->children[] = $folders[$foldername];
+ }
+ }
+ }
}
return $folders;
diff --git a/plugins/libkolab/lib/kolab_storage_folder_api.php b/plugins/libkolab/lib/kolab_storage_folder_api.php
index ef3309e..9e64f4e 100644
--- a/plugins/libkolab/lib/kolab_storage_folder_api.php
+++ b/plugins/libkolab/lib/kolab_storage_folder_api.php
@@ -326,5 +326,14 @@ abstract class kolab_storage_folder_api
return $subscribed ? kolab_storage::folder_subscribe($this->name) : kolab_storage::folder_unsubscribe($this->name);
}
+ /**
+ * Return folder name as string representation of this object
+ *
+ * @return string Full IMAP folder name
+ */
+ public function __toString()
+ {
+ return $this->name;
+ }
}
diff --git a/plugins/libkolab/lib/kolab_storage_folder_user.php b/plugins/libkolab/lib/kolab_storage_folder_user.php
index 1c37da9..7c141c5 100644
--- a/plugins/libkolab/lib/kolab_storage_folder_user.php
+++ b/plugins/libkolab/lib/kolab_storage_folder_user.php
@@ -26,6 +26,7 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
protected static $ldapcache = array();
public $ldaprec;
+ public $type;
/**
* Default constructor
@@ -85,13 +86,28 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
}
/**
- * Check subscription status of this folder
+ * Check subscription status of this folder.
+ * Subscription of a virtual user folder depends on the subscriptions of subfolders.
*
* @return boolean True if subscribed, false if not
*/
public function is_subscribed()
{
- return kolab_storage::folder_is_subscribed($this->name, true);
+ if (!empty($this->type)) {
+ $children = $subscribed = 0;
+ $delimiter = $this->imap->get_hierarchy_delimiter();
+ foreach ((array)kolab_storage::list_folders($this->name . $delimiter, '*', $this->type, false) as $subfolder) {
+ if (kolab_storage::folder_is_subscribed($subfolder)) {
+ $subscribed++;
+ }
+ $children++;
+ }
+ if ($subscribed > 0) {
+ return $subscribed == $children ? true : 2;
+ }
+ }
+
+ return false;
}
/**
@@ -103,9 +119,17 @@ class kolab_storage_folder_user extends kolab_storage_folder_virtual
*/
public function subscribe($subscribed)
{
- return $subscribed ?
- kolab_storage::folder_subscribe($this->name, true) :
- kolab_storage::folder_unsubscribe($this->name, true);
+ $success = false;
+
+ // (un)subscribe all subfolders of a given type
+ if (!empty($this->type)) {
+ $delimiter = $this->imap->get_hierarchy_delimiter();
+ foreach ((array)kolab_storage::list_folders($this->name . $delimiter, '*', $this->type, false) as $subfolder) {
+ $success |= ($subscribed ? kolab_storage::folder_subscribe($subfolder) : kolab_storage::folder_unsubscribe($subfolder));
+ }
+ }
+
+ return $success;
}
} \ No newline at end of file