diff --git a/program/include/rcmail.php b/program/include/rcmail.php index 83f945fce..a20ae8ad7 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -1635,7 +1635,7 @@ class rcmail extends rcube $is_collapsed = strpos($collapsed, '&'.rawurlencode($folder['id']).'&') !== false; $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0; - if ($folder_class && !$realnames) { + if ($folder_class && !$realnames && $this->text_exists($folder_class)) { $foldername = $this->gettext($folder_class); } else { @@ -1733,7 +1733,7 @@ class rcmail extends rcube } } - if (!$realnames && ($folder_class = $this->folder_classname($folder['id']))) { + if (!$realnames && ($folder_class = $this->folder_classname($folder['id'])) && $this->text_exists($folder_class)) { $foldername = $this->gettext($folder_class); } else { @@ -1757,21 +1757,43 @@ class rcmail extends rcube } /** - * Return internal name for the given folder if it matches the configured special folders + * Returns class name for the given folder if it is a special folder + * (including shared/other users namespace roots). + * + * @param string $folder_id IMAP Folder name + * + * @return string|null CSS class name */ public function folder_classname($folder_id) { - if ($folder_id == 'INBOX') { - return 'inbox'; - } + static $classes; + + if ($classes === null) { + $classes = array('INBOX' => 'inbox'); - // for these mailboxes we have localized labels and css classes - foreach (array('sent', 'drafts', 'trash', 'junk') as $smbx) - { - if ($folder_id === $this->config->get($smbx.'_mbox')) { - return $smbx; + // for these mailboxes we have css classes + foreach (array('sent', 'drafts', 'trash', 'junk') as $type) { + if (($mbox = $this->config->get($type . '_mbox')) && !isset($classes[$mbox])) { + $classes[$mbox] = $type; + } + } + + $storage = $this->get_storage(); + + // add classes for shared/other user namespace roots + foreach (array('other', 'shared') as $ns_name) { + if ($ns = $storage->get_namespace($ns_name)) { + foreach ($ns as $root) { + $root = substr($root[0], 0, -1); + if (strlen($root) && !isset($classes[$root])) { + $classes[$root] = "ns-$ns_name"; + } + } + } } } + + return $classes[$folder_id]; } /** @@ -1788,7 +1810,7 @@ class rcmail extends rcube { $realnames = $this->config->get('show_real_foldernames'); - if (!$realnames && ($folder_class = $this->folder_classname($name))) { + if (!$realnames && ($folder_class = $this->folder_classname($name)) && $this->text_exists($folder_class)) { return $this->gettext($folder_class); } @@ -1809,8 +1831,10 @@ class rcmail extends rcube if ($count > 1) { for ($i = 1; $i < $count; $i++) { - $folder = implode($delimiter, array_slice($path, 0, -$i)); - if ($folder_class = $this->folder_classname($folder)) { + $folder = implode($delimiter, array_slice($path, 0, -$i)); + $folder_class = $this->folder_classname($folder); + + if ($folder_class && $this->text_exists($folder_class)) { $name = implode($delimiter, array_slice($path, $count - $i)); $name = rcube_charset::convert($name, 'UTF7-IMAP'); diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php index 77baf95b6..a26cc4fb9 100644 --- a/program/lib/Roundcube/rcube_imap.php +++ b/program/lib/Roundcube/rcube_imap.php @@ -4328,17 +4328,17 @@ class rcube_imap extends rcube_storage } /** - * Sort folders first by default folders and then in alphabethical order + * Sort folders in alphabethical order. Optionally put special folders + * first and other-users/shared namespaces last. * * @param array $a_folders Folders list - * @param bool $skip_default Skip default folders handling + * @param bool $skip_special Skip special folders handling * * @return array Sorted list */ - public function sort_folder_list($a_folders, $skip_default = false) + public function sort_folder_list($a_folders, $skip_special = false) { - $specials = array_merge(array('INBOX'), array_values($this->get_special_folders())); - $folders = array(); + $folders = array(); // convert names to UTF-8 foreach ($a_folders as $folder) { @@ -4353,21 +4353,49 @@ class rcube_imap extends rcube_storage $folders = array_keys($folders); - if ($skip_default) { + if ($skip_special || empty($folders)) { return $folders; } - // force the type of folder name variable (#1485527) - $folders = array_map('strval', $folders); - $out = array(); + // Collect special folders and non-personal namespace roots + $specials = array_merge(array('INBOX'), array_values($this->get_special_folders())); + $ns_roots = array(); - // finally we must put special folders on top and rebuild the list - // to move their subfolders where they belong... + foreach (array('other', 'shared') as $ns_name) { + if ($ns = $this->get_namespace($ns_name)) { + foreach ($ns as $root) { + $ns_roots[rtrim($root[0], $root[1])] = $root[0]; + } + } + } + + // Force the type of folder name variable (#1485527) + $folders = array_map('strval', $folders); + $out = array(); + + // Put special folders on top... $specials = array_unique(array_intersect($specials, $folders)); $folders = array_merge($specials, array_diff($folders, $specials)); + // ... and rebuild the list to move their subfolders where they belong $this->sort_folder_specials(null, $folders, $specials, $out); + // Put other-user/shared namespaces at the end + if (!empty($ns_roots)) { + $folders = array(); + foreach ($out as $folder) { + foreach ($ns_roots as $root => $prefix) { + if ($folder === $root || strpos($folder, $prefix) === 0) { + $folders[] = $folder; + } + } + } + + if (!empty($folders)) { + $out = array_merge(array_diff($out, $folders), $folders); + } + } + return $out; } diff --git a/skins/elastic/styles/widgets/lists.less b/skins/elastic/styles/widgets/lists.less index 06406e313..490023eb9 100644 --- a/skins/elastic/styles/widgets/lists.less +++ b/skins/elastic/styles/widgets/lists.less @@ -540,6 +540,12 @@ ul.treelist { &.archive > a:before { .font-icon-solid(@fa-var-archive); } + &.ns-shared > a:before { + .font-icon-solid(@fa-var-share-alt); + } + &.ns-other > a:before { + .font-icon-solid(@fa-var-user-friends); + } } // folder-selector fix for left padding