diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | program/js/app.js | 36 | ||||
-rw-r--r-- | program/js/treelist.js | 7 | ||||
-rw-r--r-- | program/localization/en_US/labels.inc | 3 | ||||
-rw-r--r-- | program/steps/settings/folders.inc | 49 | ||||
-rw-r--r-- | skins/classic/functions.js | 5 | ||||
-rw-r--r-- | skins/classic/settings.css | 5 | ||||
-rw-r--r-- | skins/classic/templates/folders.html | 1 | ||||
-rw-r--r-- | skins/larry/settings.css | 5 | ||||
-rw-r--r-- | skins/larry/styles.css | 1 | ||||
-rw-r--r-- | skins/larry/templates/folders.html | 1 | ||||
-rw-r--r-- | skins/larry/ui.js | 5 |
12 files changed, 109 insertions, 10 deletions
@@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Added namespace filter in Folder Manager - Added folder searching in Folder Manager - Added config option 'imap_log_session' to enable Roundcube <-> IMAP session ID logging - Added config option 'log_session_id' to control the lengh of the session identifer in logs diff --git a/program/js/app.js b/program/js/app.js index c64318858..5a8734772 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -5862,8 +5862,9 @@ function rcube_webmail() row.attr({id: 'rcmli' + this.html_identifier_encode(id), 'class': class_name}); if (!refrow || !refrow.length) { - // remove old subfolders and toggle + // remove old data, subfolders and toggle $('ul,div.treetoggle', row).remove(); + row.removeData('filtered'); } // set folder name @@ -5990,7 +5991,7 @@ function rcube_webmail() this.subscription_list.expand(this.folder_id2name(parent.id)); } - row = row.get(0); + row = row.show().get(0); if (row.scrollIntoView) row.scrollIntoView(); @@ -6134,6 +6135,37 @@ function rcube_webmail() $('#folder-size').replaceWith(size); }; + // filter folders by namespace + this.folder_filter = function(prefix) + { + this.subscription_list.reset_search(); + + this.subscription_list.container.children('li').each(function() { + var i, folder = ref.folder_id2name(this.id); + // show all folders + if (prefix == '---') { + } + // got namespace prefix + else if (prefix) { + if (folder !== prefix) { + $(this).data('filtered', true).hide(); + return + } + } + // no namespace prefix, filter out all other namespaces + else { + // first get all namespace roots + for (i in ref.env.ns_roots) { + if (folder === ref.env.ns_roots[i]) { + $(this).data('filtered', true).hide(); + return; + } + } + } + + $(this).removeData('filtered').show(); + }); + }; /*********************************************************/ /********* GUI functionality *********/ diff --git a/program/js/treelist.js b/program/js/treelist.js index cc1880da2..5e6d326fc 100644 --- a/program/js/treelist.js +++ b/program/js/treelist.js @@ -522,6 +522,11 @@ function rcube_treelist_widget(node, p) var li, sli; if (!node.virtual && !node.deleted && String(node.text).toLowerCase().indexOf(q) >= 0 && hits.indexOf(node.id) < 0) { li = id2dom(node.id); + + // skip already filtered nodes + if (li.data('filtered')) + return; + sli = $('<li>') .attr('id', li.attr('id') + '--xsR') .attr('class', li.attr('class')) @@ -566,7 +571,7 @@ function rcube_treelist_widget(node, p) searchfield.val(''); $(container).children('li.searchresult__').remove(); - $(container).children('li').show(); + $(container).children('li').filter(function() { return !$(this).data('filtered'); }).show(); search_active = false; diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index e3fe76b2b..449b278f8 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -549,6 +549,9 @@ $labels['personalfolder'] = 'Private Folder'; $labels['otherfolder'] = 'Other User\'s Folder'; $labels['sharedfolder'] = 'Public Folder'; $labels['findfolders'] = 'Find folders'; +$labels['namespace.personal'] = 'Personal'; +$labels['namespace.other'] = 'Other users'; +$labels['namespace.shared'] = 'Shared'; $labels['sortby'] = 'Sort by'; $labels['sortasc'] = 'Sort ascending'; diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc index 061cd8893..14e41d607 100644 --- a/program/steps/settings/folders.inc +++ b/program/steps/settings/folders.inc @@ -181,8 +181,9 @@ $OUTPUT->add_label('deletefolderconfirm', 'purgefolderconfirm', 'folderdeleting' // register UI objects $OUTPUT->add_handlers(array( - 'foldersubscription' => 'rcube_subscription_form', + 'foldersubscription' => 'rcmail_subscription_form', 'folderframe' => 'rcmail_folder_frame', + 'folderfilter' => 'rcmail_folder_filter', 'quotadisplay' => array($RCMAIL, 'quota_display'), )); @@ -190,7 +191,7 @@ $OUTPUT->send('folders'); // build table with all folders listed by server -function rcube_subscription_form($attrib) +function rcmail_subscription_form($attrib) { global $RCMAIL, $OUTPUT; @@ -424,6 +425,50 @@ function rcmail_folder_frame($attrib) return $OUTPUT->frame($attrib, true); } +function rcmail_folder_filter($attrib) +{ + global $RCMAIL; + + $storage = $RCMAIL->get_storage(); + $namespace = $storage->get_namespace(); + + if (empty($namespace['personal']) && empty($namespace['shared']) && empty($namespace['other'])) { + return ''; + } + + if (!$attrib['id']) { + $attrib['id'] = 'rcmfolderfilter'; + } + + $attrib['onchange'] = rcmail_output::JS_OBJECT_NAME . '.folder_filter(this.value)'; + + $roots = array(); + $select = new html_select($attrib); + $select->add($RCMAIL->gettext('all'), '---'); + + foreach (array_keys($namespace) as $type) { + foreach ((array)$namespace[$type] as $ns) { + $root = rtrim($ns[0], $ns[1]); + $label = $RCMAIL->gettext('namespace.' . $type); + + if (count($namespace[$type]) > 1) { + $label .= ' (' . rcube_charset::convert($root, 'UTF7-IMAP', RCUBE_CHARSET) . ')'; + } + + $select->add($label, $root); + + if (strlen($root)) { + $roots[] = $root; + } + } + } + + $RCMAIL->output->add_gui_object('foldersfilter', $attrib['id']); + $RCMAIL->output->set_env('ns_roots', $roots); + + return $select->show(); +} + function rcmail_rename_folder($oldname, $newname) { global $RCMAIL; diff --git a/skins/classic/functions.js b/skins/classic/functions.js index f17f393c2..2bf1538c4 100644 --- a/skins/classic/functions.js +++ b/skins/classic/functions.js @@ -644,13 +644,14 @@ folder_search_init: function(container) $('.boxtitle a.search', container).click(function(e) { var title = $('.boxtitle', container), box = $('.listsearchbox', container), - dir = box.is(':visible') ? -1 : 1; + dir = box.is(':visible') ? -1 : 1, + height = 24 + ($('select', box).length ? 24 : 0); box.slideToggle({ duration: 160, progress: function(animation, progress) { if (dir < 0) progress = 1 - progress; - $('.boxlistcontent', container).css('top', (title.outerHeight() + 24 * progress) + 'px'); + $('.boxlistcontent', container).css('top', (title.outerHeight() + height * progress) + 'px'); }, complete: function() { box.toggleClass('expanded'); diff --git a/skins/classic/settings.css b/skins/classic/settings.css index cd250d57e..9dda7bb8d 100644 --- a/skins/classic/settings.css +++ b/skins/classic/settings.css @@ -21,6 +21,11 @@ text-indent: 50000px; } +.listsearchbox select { + width: 100%; + margin: 1px 0; +} + #identities-table, #sections-table { diff --git a/skins/classic/templates/folders.html b/skins/classic/templates/folders.html index 8ed0b5fdc..ac824306f 100644 --- a/skins/classic/templates/folders.html +++ b/skins/classic/templates/folders.html @@ -29,6 +29,7 @@ <a class="iconbutton searchicon"></a> <roundcube:button command="reset-foldersearch" id="folderlistsearch-reset" class="iconbutton reset" title="resetsearch" width="13" height="13" /> </div> + <roundcube:object name="folderfilter" id="folderlist-filter" /> </div> <div id="folderlist-content" class="boxlistcontent"> <roundcube:object name="foldersubscription" form="subscriptionform" id="subscription-table" diff --git a/skins/larry/settings.css b/skins/larry/settings.css index cda47b631..b2779982c 100644 --- a/skins/larry/settings.css +++ b/skins/larry/settings.css @@ -224,6 +224,11 @@ top: 34px; } +.listsearchbox select { + width: 100%; + margin: 3px 0; +} + #folderslist, #identitieslist { position: absolute; diff --git a/skins/larry/styles.css b/skins/larry/styles.css index d7fd588a8..b2b4f9a05 100644 --- a/skins/larry/styles.css +++ b/skins/larry/styles.css @@ -1957,7 +1957,6 @@ ul.proplist li { } .listsearchbox { - position: relative; padding: 4px; background: #c7e3ef; display: none; diff --git a/skins/larry/templates/folders.html b/skins/larry/templates/folders.html index 3d016cad1..977dff451 100644 --- a/skins/larry/templates/folders.html +++ b/skins/larry/templates/folders.html @@ -29,6 +29,7 @@ <a class="iconbutton searchicon"></a> <roundcube:button command="reset-foldersearch" id="folderlistsearch-reset" class="iconbutton reset" title="resetsearch" label="resetsearch" /> </div> + <roundcube:object name="folderfilter" id="folderlist-filter" /> </div> <div id="folderslist-content" class="scroller withfooter"> <roundcube:object name="foldersubscription" form="subscriptionform" id="subscription-table" class="treelist listing folderlist" /> diff --git a/skins/larry/ui.js b/skins/larry/ui.js index 1eb8e899a..7b08aeadd 100644 --- a/skins/larry/ui.js +++ b/skins/larry/ui.js @@ -540,13 +540,14 @@ function rcube_mail_ui() $('.boxtitle a.search', container).click(function(e) { var title = $('.boxtitle', container), box = $('.listsearchbox', container), - dir = box.is(':visible') ? -1 : 1; + dir = box.is(':visible') ? -1 : 1, + height = 34 + ($('select', box).length ? 24 : 0); box.slideToggle({ duration: 160, progress: function(animation, progress) { if (dir < 0) progress = 1 - progress; - $('.scroller', container).css('top', (title.outerHeight() + 34 * progress) + 'px'); + $('.scroller', container).css('top', (title.outerHeight() + height * progress) + 'px'); }, complete: function() { box.toggleClass('expanded'); |