mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-15 03:12:41 +01:00
7a96de10f0
Summary: Ref T2222. This restores the "N older comments are hidden." shield to all ApplicationTransactions applications. Roughly the rule this uses is that transactions older than your most recent comment are hidden, under the assumption that you've already read and dealt with them, since you replied afterward. Then we show your last comment to remind/contextualize you, and anything afterward. We also don't hide transactions if we'd only be hiding a handfull, and we never hide the few most recent transactions. This might need some #design help. Test Plan: The tricky part here is the anchor rule, which deals with the case where you follow a link to `T123#4`, but that would normally be hidden. We simulate a click on "show all" if you hit an anchor which is hidden. Here's what it looks like in Maniphest: {F112891} Reviewers: btrahan, chad Reviewed By: btrahan CC: chad, aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D8229
390 lines
9 KiB
PHP
390 lines
9 KiB
PHP
<?php
|
|
|
|
final class PHUITimelineEventView extends AphrontView {
|
|
|
|
private $userHandle;
|
|
private $title;
|
|
private $icon;
|
|
private $color;
|
|
private $classes = array();
|
|
private $contentSource;
|
|
private $dateCreated;
|
|
private $anchor;
|
|
private $isEditable;
|
|
private $isEdited;
|
|
private $transactionPHID;
|
|
private $isPreview;
|
|
private $eventGroup = array();
|
|
private $hideByDefault;
|
|
|
|
public function setHideByDefault($hide_by_default) {
|
|
$this->hideByDefault = $hide_by_default;
|
|
return $this;
|
|
}
|
|
|
|
public function getHideByDefault() {
|
|
return $this->hideByDefault;
|
|
}
|
|
|
|
public function setTransactionPHID($transaction_phid) {
|
|
$this->transactionPHID = $transaction_phid;
|
|
return $this;
|
|
}
|
|
|
|
public function getTransactionPHID() {
|
|
return $this->transactionPHID;
|
|
}
|
|
|
|
public function setIsEdited($is_edited) {
|
|
$this->isEdited = $is_edited;
|
|
return $this;
|
|
}
|
|
|
|
public function getIsEdited() {
|
|
return $this->isEdited;
|
|
}
|
|
|
|
public function setIsPreview($is_preview) {
|
|
$this->isPreview = $is_preview;
|
|
return $this;
|
|
}
|
|
|
|
public function getIsPreview() {
|
|
return $this->isPreview;
|
|
}
|
|
|
|
public function setIsEditable($is_editable) {
|
|
$this->isEditable = $is_editable;
|
|
return $this;
|
|
}
|
|
|
|
public function getIsEditable() {
|
|
return $this->isEditable;
|
|
}
|
|
|
|
public function setDateCreated($date_created) {
|
|
$this->dateCreated = $date_created;
|
|
return $this;
|
|
}
|
|
|
|
public function getDateCreated() {
|
|
return $this->dateCreated;
|
|
}
|
|
|
|
public function setContentSource(PhabricatorContentSource $content_source) {
|
|
$this->contentSource = $content_source;
|
|
return $this;
|
|
}
|
|
|
|
public function getContentSource() {
|
|
return $this->contentSource;
|
|
}
|
|
|
|
public function setUserHandle(PhabricatorObjectHandle $handle) {
|
|
$this->userHandle = $handle;
|
|
return $this;
|
|
}
|
|
|
|
public function setAnchor($anchor) {
|
|
$this->anchor = $anchor;
|
|
return $this;
|
|
}
|
|
|
|
public function getAnchor() {
|
|
return $this->anchor;
|
|
}
|
|
|
|
public function setTitle($title) {
|
|
$this->title = $title;
|
|
return $this;
|
|
}
|
|
|
|
public function addClass($class) {
|
|
$this->classes[] = $class;
|
|
return $this;
|
|
}
|
|
|
|
public function setIcon($icon) {
|
|
$this->icon = $icon;
|
|
return $this;
|
|
}
|
|
|
|
public function setColor($color) {
|
|
$this->color = $color;
|
|
return $this;
|
|
}
|
|
|
|
public function getEventGroup() {
|
|
return array_merge(array($this), $this->eventGroup);
|
|
}
|
|
|
|
public function addEventToGroup(PHUITimelineEventView $event) {
|
|
$this->eventGroup[] = $event;
|
|
return $this;
|
|
}
|
|
|
|
protected function renderEventTitle($is_first_event, $force_icon) {
|
|
$title = $this->title;
|
|
if (($title === null) && !$this->hasChildren()) {
|
|
$title = '';
|
|
}
|
|
|
|
if ($is_first_event) {
|
|
$extra = array();
|
|
$is_first_extra = true;
|
|
foreach ($this->getEventGroup() as $event) {
|
|
$extra[] = $event->renderExtra($is_first_extra);
|
|
$is_first_extra = false;
|
|
}
|
|
$extra = array_reverse($extra);
|
|
$extra = array_mergev($extra);
|
|
$extra = phutil_tag(
|
|
'span',
|
|
array(
|
|
'class' => 'phui-timeline-extra',
|
|
),
|
|
phutil_implode_html(" \xC2\xB7 ", $extra));
|
|
} else {
|
|
$extra = null;
|
|
}
|
|
|
|
if ($title !== null || $extra) {
|
|
$title_classes = array();
|
|
$title_classes[] = 'phui-timeline-title';
|
|
|
|
$icon = null;
|
|
if ($this->icon || $force_icon) {
|
|
$title_classes[] = 'phui-timeline-title-with-icon';
|
|
}
|
|
|
|
if ($this->icon) {
|
|
$fill_classes = array();
|
|
$fill_classes[] = 'phui-timeline-icon-fill';
|
|
if ($this->color) {
|
|
$fill_classes[] = 'phui-timeline-icon-fill-'.$this->color;
|
|
}
|
|
|
|
$icon = phutil_tag(
|
|
'span',
|
|
array(
|
|
'class' => implode(' ', $fill_classes),
|
|
),
|
|
phutil_tag(
|
|
'span',
|
|
array(
|
|
'class' => 'phui-timeline-icon sprite-icons '.
|
|
'icons-'.$this->icon.'-white',
|
|
),
|
|
''));
|
|
}
|
|
|
|
$title = phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => implode(' ', $title_classes),
|
|
),
|
|
array($icon, $title, $extra));
|
|
}
|
|
|
|
return $title;
|
|
}
|
|
|
|
public function render() {
|
|
|
|
$events = $this->getEventGroup();
|
|
|
|
// Move events with icons first.
|
|
$icon_keys = array();
|
|
foreach ($this->getEventGroup() as $key => $event) {
|
|
if ($event->icon) {
|
|
$icon_keys[] = $key;
|
|
}
|
|
}
|
|
$events = array_select_keys($events, $icon_keys) + $events;
|
|
$force_icon = (bool)$icon_keys;
|
|
|
|
$group_titles = array();
|
|
$group_children = array();
|
|
$is_first_event = true;
|
|
foreach ($events as $event) {
|
|
$group_titles[] = $event->renderEventTitle($is_first_event, $force_icon);
|
|
$is_first_event = false;
|
|
if ($event->hasChildren()) {
|
|
$group_children[] = $event->renderChildren();
|
|
}
|
|
}
|
|
|
|
$wedge = phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => 'phui-timeline-wedge phui-timeline-border',
|
|
),
|
|
'');
|
|
|
|
$image_uri = $this->userHandle->getImageURI();
|
|
$image = phutil_tag(
|
|
'div',
|
|
array(
|
|
'style' => 'background-image: url('.$image_uri.')',
|
|
'class' => 'phui-timeline-image',
|
|
),
|
|
'');
|
|
|
|
$content_classes = array();
|
|
$content_classes[] = 'phui-timeline-content';
|
|
|
|
$classes = array();
|
|
$classes[] = 'phui-timeline-event-view';
|
|
if ($group_children) {
|
|
$classes[] = 'phui-timeline-major-event';
|
|
$content = phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => 'phui-timeline-inner-content',
|
|
),
|
|
array(
|
|
$group_titles,
|
|
phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => 'phui-timeline-core-content',
|
|
),
|
|
$group_children),
|
|
));
|
|
} else {
|
|
$classes[] = 'phui-timeline-minor-event';
|
|
$content = $group_titles;
|
|
}
|
|
|
|
$content = phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => 'phui-timeline-group phui-timeline-border',
|
|
),
|
|
$content);
|
|
|
|
$content = phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => implode(' ', $content_classes),
|
|
),
|
|
array($image, $wedge, $content));
|
|
|
|
$outer_classes = $this->classes;
|
|
$outer_classes[] = 'phui-timeline-shell';
|
|
$color = null;
|
|
foreach ($this->getEventGroup() as $event) {
|
|
if ($event->color) {
|
|
$color = $event->color;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($color) {
|
|
$outer_classes[] = 'phui-timeline-'.$color;
|
|
}
|
|
|
|
$sigil = null;
|
|
$meta = null;
|
|
if ($this->getTransactionPHID()) {
|
|
$sigil = 'transaction';
|
|
$meta = array(
|
|
'phid' => $this->getTransactionPHID(),
|
|
'anchor' => $this->anchor,
|
|
);
|
|
}
|
|
|
|
return javelin_tag(
|
|
'div',
|
|
array(
|
|
'class' => implode(' ', $outer_classes),
|
|
'id' => $this->anchor ? 'anchor-'.$this->anchor : null,
|
|
'sigil' => $sigil,
|
|
'meta' => $meta,
|
|
),
|
|
phutil_tag(
|
|
'div',
|
|
array(
|
|
'class' => implode(' ', $classes),
|
|
),
|
|
$content));
|
|
}
|
|
|
|
private function renderExtra($is_first_extra) {
|
|
$extra = array();
|
|
|
|
if ($this->getIsPreview()) {
|
|
$extra[] = pht('PREVIEW');
|
|
} else {
|
|
$xaction_phid = $this->getTransactionPHID();
|
|
|
|
if ($this->getIsEdited()) {
|
|
$extra[] = javelin_tag(
|
|
'a',
|
|
array(
|
|
'href' => '/transactions/history/'.$xaction_phid.'/',
|
|
'sigil' => 'workflow',
|
|
),
|
|
pht('Edited'));
|
|
}
|
|
|
|
if ($this->getIsEditable()) {
|
|
$extra[] = javelin_tag(
|
|
'a',
|
|
array(
|
|
'href' => '/transactions/edit/'.$xaction_phid.'/',
|
|
'sigil' => 'workflow transaction-edit',
|
|
),
|
|
pht('Edit'));
|
|
}
|
|
|
|
if ($is_first_extra) {
|
|
$source = $this->getContentSource();
|
|
if ($source) {
|
|
$extra[] = id(new PhabricatorContentSourceView())
|
|
->setContentSource($source)
|
|
->setUser($this->getUser())
|
|
->render();
|
|
}
|
|
|
|
$date_created = null;
|
|
foreach ($this->getEventGroup() as $event) {
|
|
if ($event->getDateCreated()) {
|
|
if ($date_created === null) {
|
|
$date_created = $event->getDateCreated();
|
|
} else {
|
|
$date_created = min($event->getDateCreated(), $date_created);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($date_created) {
|
|
$date = phabricator_datetime(
|
|
$this->getDateCreated(),
|
|
$this->getUser());
|
|
if ($this->anchor) {
|
|
Javelin::initBehavior('phabricator-watch-anchor');
|
|
|
|
$anchor = id(new PhabricatorAnchorView())
|
|
->setAnchorName($this->anchor)
|
|
->render();
|
|
|
|
$date = array(
|
|
$anchor,
|
|
phutil_tag(
|
|
'a',
|
|
array(
|
|
'href' => '#'.$this->anchor,
|
|
),
|
|
$date),
|
|
);
|
|
}
|
|
$extra[] = $date;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $extra;
|
|
}
|
|
|
|
}
|