diff --git a/src/applications/differential/view/DifferentialRevisionListView.php b/src/applications/differential/view/DifferentialRevisionListView.php index 1e07240265..d14a300fb2 100644 --- a/src/applications/differential/view/DifferentialRevisionListView.php +++ b/src/applications/differential/view/DifferentialRevisionListView.php @@ -114,8 +114,15 @@ final class DifferentialRevisionListView extends AphrontView { $list = new PhabricatorObjectItemListView(); $list->setCards(true); + $do_not_display_age = array( + ArcanistDifferentialRevisionStatus::CLOSED => true, + ArcanistDifferentialRevisionStatus::ABANDONED => true, + ); + foreach ($this->revisions as $revision) { - $item = new PhabricatorObjectItemView(); + $item = id(new PhabricatorObjectItemView()) + ->setUser($user); + $rev_fields = array(); $icons = array(); @@ -136,23 +143,21 @@ final class DifferentialRevisionListView extends AphrontView { $modified = $revision->getDateModified(); + $status = $revision->getStatus(); + $show_age = ($fresh || $stale) && + $this->highlightAge && + empty($do_not_display_age[$status]); + + + $object_age = PhabricatorObjectItemView::AGE_FRESH; foreach ($this->fields as $field) { - if (($fresh || $stale) && - $field instanceof DifferentialDateModifiedFieldSpecification) { - if ($stale && $modified < $stale) { - $days = floor((time() - $modified) / 60 / 60 / 24); - $icons['age'] = array( - 'icon' => 'warning-grey', - 'label' => pht('Old (%d days)', $days), - ); - } else if ($fresh && $modified < $fresh) { - $days = floor((time() - $modified) / 60 / 60 / 24); - $icons['age'] = array( - 'icon' => 'perflab-grey', - 'label' => pht('Stale (%d days)', $days), - ); - } else { - // Fresh, noOp(); + if ($show_age) { + if ($field instanceof DifferentialDateModifiedFieldSpecification) { + if ($stale && $modified < $stale) { + $object_age = PhabricatorObjectItemView::AGE_OLD; + } else if ($fresh && $modified < $fresh) { + $object_age = PhabricatorObjectItemView::AGE_STALE; + } } } @@ -161,7 +166,6 @@ final class DifferentialRevisionListView extends AphrontView { ->renderValueForRevisionList($revision); } - $status = $revision->getStatus(); $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status); @@ -195,22 +199,7 @@ final class DifferentialRevisionListView extends AphrontView { // Reviewers $item->addAttribute(pht('Reviewers: %s', $rev_fields['Reviewers'])); - $time_icon = 'none'; - $time_attr = array(); - if ($this->highlightAge) { - $do_not_display_age = array( - ArcanistDifferentialRevisionStatus::CLOSED => true, - ArcanistDifferentialRevisionStatus::ABANDONED => true, - ); - if (isset($icons['age']) && !isset($do_not_display_age[$status])) { - $time_icon = $icons['age']['icon']; - $time_attr = array( - 'tip' => $icons['age']['label'], - ); - } - } - - $item->addIcon($time_icon, $rev_fields['Updated'], $time_attr); + $item->setEpoch($revision->getDateModified(), $object_age); // First remove the fields we already have $count = 7; diff --git a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php index fee2a0b772..2614affcad 100644 --- a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php +++ b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php @@ -667,6 +667,17 @@ abstract class PhabricatorBaseEnglishTranslation '%d Open Pull Requests', ), + 'Stale (%s day(s))' => array( + 'Stale (%s day)', + 'Stale (%s days)', + ), + + 'Old (%s day(s))' => array( + 'Old (%s day)', + 'Old (%s days)', + ), + + ); } diff --git a/src/view/layout/PhabricatorObjectItemView.php b/src/view/layout/PhabricatorObjectItemView.php index 4f93f46b84..84f302724f 100644 --- a/src/view/layout/PhabricatorObjectItemView.php +++ b/src/view/layout/PhabricatorObjectItemView.php @@ -19,6 +19,10 @@ final class PhabricatorObjectItemView extends AphrontTagView { private $headIcons = array(); private $disabled; + const AGE_FRESH = 'fresh'; + const AGE_STALE = 'stale'; + const AGE_OLD = 'old'; + public function setDisabled($disabled) { $this->disabled = $disabled; return $this; @@ -93,6 +97,40 @@ final class PhabricatorObjectItemView extends AphrontTagView { return $this; } + public function setEpoch($epoch, $age = self::AGE_FRESH) { + $date = phabricator_datetime($epoch, $this->getUser()); + + $days = floor((time() - $epoch) / 60 / 60 / 24); + + switch ($age) { + case self::AGE_FRESH: + $this->addIcon('none', $date); + break; + case self::AGE_STALE: + require_celerity_resource('sprite-status-css'); + $attr = array( + 'tip' => pht('Stale (%s day(s))', new PhutilNumber($days)), + 'class' => 'icon-age-stale', + 'sheet' => PHUIIconView::SPRITE_STATUS, + ); + $this->addIcon('time-yellow', $date, $attr); + break; + case self::AGE_OLD: + require_celerity_resource('sprite-status-css'); + $attr = array( + 'tip' => pht('Old (%s day(s))', new PhutilNumber($days)), + 'class' => 'icon-age-old', + 'sheet' => PHUIIconView::SPRITE_STATUS, + ); + $this->addIcon('time-red', $date, $attr); + break; + default: + throw new Exception("Unknown age '{$age}'!"); + } + + return $this; + } + public function addAction(PHUIListItemView $action) { if (count($this->actions) >= 3) { throw new Exception("Limit 3 actions per item."); @@ -261,11 +299,13 @@ final class PhabricatorObjectItemView extends AphrontTagView { ); } + $sheet = idx($spec['attributes'], 'sheet', 'icons'); + $icon = javelin_tag( 'span', array( 'class' => 'phabricator-object-item-icon-image '. - 'sprite-icons icons-'.$icon, + 'sprite-'.$sheet.' '.$sheet.'-'.$icon, 'sigil' => $sigil, 'meta' => $meta, ), @@ -292,6 +332,9 @@ final class PhabricatorObjectItemView extends AphrontTagView { if ($spec['icon'] == 'none') { $classes[] = 'phabricator-object-item-icon-none'; } + if (isset($spec['attributes']['class'])) { + $classes[] = $spec['attributes']['class']; + } $icon_list[] = javelin_tag( 'li',