3 final class PHUITimelineView
extends AphrontView
{
5 private $events = array();
7 private $shouldTerminate = false;
8 private $shouldAddSpacers = true;
10 private $viewData = array();
11 private $quoteTargetID;
14 public function setID($id) {
19 public function setShouldTerminate($term) {
20 $this->shouldTerminate
= $term;
24 public function setShouldAddSpacers($bool) {
25 $this->shouldAddSpacers
= $bool;
29 public function setPager(AphrontCursorPagerView
$pager) {
30 $this->pager
= $pager;
34 public function getPager() {
38 public function addEvent(PHUITimelineEventView
$event) {
39 $this->events
[] = $event;
43 public function setViewData(array $data) {
44 $this->viewData
= $data;
48 public function getViewData() {
49 return $this->viewData
;
52 public function setQuoteTargetID($quote_target_id) {
53 $this->quoteTargetID
= $quote_target_id;
57 public function getQuoteTargetID() {
58 return $this->quoteTargetID
;
61 public function setQuoteRef($quote_ref) {
62 $this->quoteRef
= $quote_ref;
66 public function getQuoteRef() {
67 return $this->quoteRef
;
70 public function render() {
71 if ($this->getPager()) {
72 if ($this->id
=== null) {
73 $this->id
= celerity_generate_unique_node_id();
75 Javelin
::initBehavior(
76 'phabricator-show-older-transactions',
78 'timelineID' => $this->id
,
79 'viewData' => $this->getViewData(),
82 $events = $this->buildEvents();
87 'class' => 'phui-timeline-view',
94 'class' => 'aural-only',
96 pht('Event Timeline')),
101 public function buildEvents() {
102 require_celerity_resource('phui-timeline-view-css');
104 $spacer = self
::renderSpacer();
106 // Track why we're hiding older results.
112 // Bucket timeline events into events we'll hide by default (because they
113 // predate your most recent interaction with the object) and events we'll
115 foreach ($this->events
as $event) {
116 if ($event->getHideByDefault()) {
123 // If you've never interacted with the object, all the events will be shown
124 // by default. We may still need to paginate if there are a large number
129 $hide_reason = 'comment';
132 if ($this->getPager()) {
133 if ($this->getPager()->getHasMoreResults()) {
135 $hide_reason = 'limit';
142 if ($more && $this->getPager()) {
143 switch ($hide_reason) {
146 'Changes from before your most recent comment are hidden.');
151 'There are a very large number of changes, so older changes are '.
156 $uri = $this->getPager()->getNextPageURI();
158 $target_id = $this->getQuoteTargetID();
159 if ($target_id === null) {
160 $uri->removeQueryParam('quoteTargetID');
162 $uri->replaceQueryParam('quoteTargetID', $target_id);
165 $quote_ref = $this->getQuoteRef();
166 if ($quote_ref === null) {
167 $uri->removeQueryParam('quoteRef');
169 $uri->replaceQueryParam('quoteRef', $quote_ref);
172 $events[] = javelin_tag(
175 'sigil' => 'show-older-block',
176 'class' => 'phui-timeline-older-transactions-are-hidden',
184 'href' => (string)$uri,
185 'mustcapture' => true,
186 'sigil' => 'show-older-link',
188 pht('Show Older Changes')),
197 $this->prepareBadgeData($show);
198 $events[] = phutil_implode_html($spacer, $show);
202 if ($this->shouldAddSpacers
) {
203 $events = array($spacer, $events, $spacer);
206 $events = array($spacer);
209 if ($this->shouldTerminate
) {
210 $events[] = self
::renderEnder();
216 public static function renderSpacer() {
220 'class' => 'phui-timeline-event-view '.
221 'phui-timeline-spacer',
226 public static function renderEnder() {
230 'class' => 'phui-timeline-event-view '.
236 private function prepareBadgeData(array $events) {
237 assert_instances_of($events, 'PHUITimelineEventView');
239 $viewer = $this->getUser();
240 $can_use_badges = PhabricatorApplication
::isClassInstalledForViewer(
241 'PhabricatorBadgesApplication',
243 if (!$can_use_badges) {
247 $user_phid_type = PhabricatorPeopleUserPHIDType
::TYPECONST
;
249 $user_phids = array();
250 foreach ($events as $key => $event) {
251 $author_phid = $event->getAuthorPHID();
253 unset($events[$key]);
257 if (phid_get_type($author_phid) != $user_phid_type) {
258 // This is likely an application actor, like "Herald" or "Harbormaster".
259 // They can't have badges.
260 unset($events[$key]);
264 $user_phids[$author_phid] = $author_phid;
271 $users = id(new PhabricatorPeopleQuery())
273 ->withPHIDs($user_phids)
274 ->needBadgeAwards(true)
276 $users = mpull($users, null, 'getPHID');
278 foreach ($events as $event) {
279 $user_phid = $event->getAuthorPHID();
280 if (!array_key_exists($user_phid, $users)) {
283 $badges = $users[$user_phid]->getRecentBadgeAwards();
284 foreach ($badges as $badge) {
285 $badge_view = id(new PHUIBadgeMiniView())
286 ->setIcon($badge['icon'])
287 ->setQuality($badge['quality'])
288 ->setHeader($badge['name'])
289 ->setTipDirection('E')
290 ->setHref('/badges/view/'.$badge['id'].'/');
291 $event->addBadge($badge_view);