[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PHUITimelineEventView extends AphrontView { 4 5 const DELIMITER = " \xC2\xB7 "; 6 7 private $userHandle; 8 private $title; 9 private $icon; 10 private $color; 11 private $classes = array(); 12 private $contentSource; 13 private $dateCreated; 14 private $anchor; 15 private $isEditable; 16 private $isEdited; 17 private $isRemovable; 18 private $transactionPHID; 19 private $isPreview; 20 private $eventGroup = array(); 21 private $hideByDefault; 22 private $token; 23 private $tokenRemoved; 24 private $quoteTargetID; 25 private $quoteRef; 26 private $reallyMajorEvent; 27 28 public function setQuoteRef($quote_ref) { 29 $this->quoteRef = $quote_ref; 30 return $this; 31 } 32 33 public function getQuoteRef() { 34 return $this->quoteRef; 35 } 36 37 public function setQuoteTargetID($quote_target_id) { 38 $this->quoteTargetID = $quote_target_id; 39 return $this; 40 } 41 42 public function getQuoteTargetID() { 43 return $this->quoteTargetID; 44 } 45 46 public function setHideByDefault($hide_by_default) { 47 $this->hideByDefault = $hide_by_default; 48 return $this; 49 } 50 51 public function getHideByDefault() { 52 return $this->hideByDefault; 53 } 54 55 public function setTransactionPHID($transaction_phid) { 56 $this->transactionPHID = $transaction_phid; 57 return $this; 58 } 59 60 public function getTransactionPHID() { 61 return $this->transactionPHID; 62 } 63 64 public function setIsEdited($is_edited) { 65 $this->isEdited = $is_edited; 66 return $this; 67 } 68 69 public function getIsEdited() { 70 return $this->isEdited; 71 } 72 73 public function setIsPreview($is_preview) { 74 $this->isPreview = $is_preview; 75 return $this; 76 } 77 78 public function getIsPreview() { 79 return $this->isPreview; 80 } 81 82 public function setIsEditable($is_editable) { 83 $this->isEditable = $is_editable; 84 return $this; 85 } 86 87 public function getIsEditable() { 88 return $this->isEditable; 89 } 90 91 public function setIsRemovable($is_removable) { 92 $this->isRemovable = $is_removable; 93 return $this; 94 } 95 96 public function getIsRemovable() { 97 return $this->isRemovable; 98 } 99 100 public function setDateCreated($date_created) { 101 $this->dateCreated = $date_created; 102 return $this; 103 } 104 105 public function getDateCreated() { 106 return $this->dateCreated; 107 } 108 109 public function setContentSource(PhabricatorContentSource $content_source) { 110 $this->contentSource = $content_source; 111 return $this; 112 } 113 114 public function getContentSource() { 115 return $this->contentSource; 116 } 117 118 public function setUserHandle(PhabricatorObjectHandle $handle) { 119 $this->userHandle = $handle; 120 return $this; 121 } 122 123 public function setAnchor($anchor) { 124 $this->anchor = $anchor; 125 return $this; 126 } 127 128 public function getAnchor() { 129 return $this->anchor; 130 } 131 132 public function setTitle($title) { 133 $this->title = $title; 134 return $this; 135 } 136 137 public function addClass($class) { 138 $this->classes[] = $class; 139 return $this; 140 } 141 142 public function setIcon($icon) { 143 $this->icon = $icon; 144 return $this; 145 } 146 147 public function setColor($color) { 148 $this->color = $color; 149 return $this; 150 } 151 152 public function setReallyMajorEvent($me) { 153 $this->reallyMajorEvent = $me; 154 return $this; 155 } 156 157 public function setToken($token, $removed = false) { 158 $this->token = $token; 159 $this->tokenRemoved = $removed; 160 return $this; 161 } 162 163 public function getEventGroup() { 164 return array_merge(array($this), $this->eventGroup); 165 } 166 167 public function addEventToGroup(PHUITimelineEventView $event) { 168 $this->eventGroup[] = $event; 169 return $this; 170 } 171 172 protected function shouldRenderEventTitle() { 173 if ($this->title === null) { 174 return false; 175 } 176 177 return true; 178 } 179 180 protected function renderEventTitle($force_icon, $has_menu, $extra) { 181 $title = $this->title; 182 183 $title_classes = array(); 184 $title_classes[] = 'phui-timeline-title'; 185 186 $icon = null; 187 if ($this->icon || $force_icon) { 188 $title_classes[] = 'phui-timeline-title-with-icon'; 189 } 190 191 if ($has_menu) { 192 $title_classes[] = 'phui-timeline-title-with-menu'; 193 } 194 195 if ($this->icon) { 196 $fill_classes = array(); 197 $fill_classes[] = 'phui-timeline-icon-fill'; 198 if ($this->color) { 199 $fill_classes[] = 'phui-timeline-icon-fill-'.$this->color; 200 } 201 202 $icon = id(new PHUIIconView()) 203 ->setIconFont($this->icon.' white') 204 ->addClass('phui-timeline-icon'); 205 206 $icon = phutil_tag( 207 'span', 208 array( 209 'class' => implode(' ', $fill_classes), 210 ), 211 $icon); 212 } 213 214 $token = null; 215 if ($this->token) { 216 $token = id(new PHUIIconView()) 217 ->addClass('phui-timeline-token') 218 ->setSpriteSheet(PHUIIconView::SPRITE_TOKENS) 219 ->setSpriteIcon($this->token); 220 if ($this->tokenRemoved) { 221 $token->addClass('strikethrough'); 222 } 223 } 224 225 $title = phutil_tag( 226 'div', 227 array( 228 'class' => implode(' ', $title_classes), 229 ), 230 array($icon, $token, $title, $extra)); 231 232 return $title; 233 } 234 235 public function render() { 236 237 $events = $this->getEventGroup(); 238 239 // Move events with icons first. 240 $icon_keys = array(); 241 foreach ($this->getEventGroup() as $key => $event) { 242 if ($event->icon) { 243 $icon_keys[] = $key; 244 } 245 } 246 $events = array_select_keys($events, $icon_keys) + $events; 247 $force_icon = (bool)$icon_keys; 248 249 $menu = null; 250 $items = array(); 251 $has_menu = false; 252 if (!$this->getIsPreview()) { 253 foreach ($this->getEventGroup() as $event) { 254 $items[] = $event->getMenuItems($this->anchor); 255 if ($event->hasChildren()) { 256 $has_menu = true; 257 } 258 } 259 $items = array_mergev($items); 260 } 261 262 if ($items || $has_menu) { 263 $icon = id(new PHUIIconView()) 264 ->setIconFont('fa-caret-down'); 265 $aural = javelin_tag( 266 'span', 267 array( 268 'aural' => true, 269 ), 270 pht('Comment Actions')); 271 272 if ($items) { 273 $sigil = 'phui-timeline-menu'; 274 Javelin::initBehavior('phui-timeline-dropdown-menu'); 275 } else { 276 $sigil = null; 277 } 278 279 $action_list = id(new PhabricatorActionListView()) 280 ->setUser($this->getUser()); 281 foreach ($items as $item) { 282 $action_list->addAction($item); 283 } 284 285 $menu = javelin_tag( 286 $items ? 'a' : 'span', 287 array( 288 'href' => '#', 289 'class' => 'phui-timeline-menu', 290 'sigil' => $sigil, 291 'aria-haspopup' => 'true', 292 'aria-expanded' => 'false', 293 'meta' => array( 294 'items' => hsprintf('%s', $action_list), 295 ), 296 ), 297 array( 298 $aural, 299 $icon, 300 )); 301 302 $has_menu = true; 303 } 304 305 // Render "extra" information (timestamp, etc). 306 $extra = $this->renderExtra($events); 307 308 $group_titles = array(); 309 $group_items = array(); 310 $group_children = array(); 311 foreach ($events as $event) { 312 if ($event->shouldRenderEventTitle()) { 313 $group_titles[] = $event->renderEventTitle( 314 $force_icon, 315 $has_menu, 316 $extra); 317 318 // Don't render this information more than once. 319 $extra = null; 320 } 321 322 if ($event->hasChildren()) { 323 $group_children[] = $event->renderChildren(); 324 } 325 } 326 327 $image_uri = $this->userHandle->getImageURI(); 328 329 $wedge = phutil_tag( 330 'div', 331 array( 332 'class' => 'phui-timeline-wedge phui-timeline-border', 333 'style' => (nonempty($image_uri)) ? '' : 'display: none;', 334 ), 335 ''); 336 337 $image = phutil_tag( 338 'div', 339 array( 340 'style' => 'background-image: url('.$image_uri.')', 341 'class' => 'phui-timeline-image', 342 ), 343 ''); 344 345 $content_classes = array(); 346 $content_classes[] = 'phui-timeline-content'; 347 348 $classes = array(); 349 $classes[] = 'phui-timeline-event-view'; 350 if ($group_children) { 351 $classes[] = 'phui-timeline-major-event'; 352 $content = phutil_tag( 353 'div', 354 array( 355 'class' => 'phui-timeline-inner-content', 356 ), 357 array( 358 $group_titles, 359 $menu, 360 phutil_tag( 361 'div', 362 array( 363 'class' => 'phui-timeline-core-content', 364 ), 365 $group_children), 366 )); 367 } else { 368 $classes[] = 'phui-timeline-minor-event'; 369 $content = $group_titles; 370 } 371 372 $content = phutil_tag( 373 'div', 374 array( 375 'class' => 'phui-timeline-group phui-timeline-border', 376 ), 377 $content); 378 379 $content = phutil_tag( 380 'div', 381 array( 382 'class' => implode(' ', $content_classes), 383 ), 384 array($image, $wedge, $content)); 385 386 $outer_classes = $this->classes; 387 $outer_classes[] = 'phui-timeline-shell'; 388 $color = null; 389 foreach ($this->getEventGroup() as $event) { 390 if ($event->color) { 391 $color = $event->color; 392 break; 393 } 394 } 395 396 if ($color) { 397 $outer_classes[] = 'phui-timeline-'.$color; 398 } 399 400 $sigil = null; 401 $meta = null; 402 if ($this->getTransactionPHID()) { 403 $sigil = 'transaction'; 404 $meta = array( 405 'phid' => $this->getTransactionPHID(), 406 'anchor' => $this->anchor, 407 ); 408 } 409 410 $major_event = null; 411 if ($this->reallyMajorEvent) { 412 $major_event = phutil_tag( 413 'div', 414 array( 415 'class' => 'phui-timeline-event-view '. 416 'phui-timeline-spacer '. 417 'phui-timeline-spacer-bold', 418 '',)); 419 } 420 421 return array( 422 javelin_tag( 423 'div', 424 array( 425 'class' => implode(' ', $outer_classes), 426 'id' => $this->anchor ? 'anchor-'.$this->anchor : null, 427 'sigil' => $sigil, 428 'meta' => $meta, 429 ), 430 phutil_tag( 431 'div', 432 array( 433 'class' => implode(' ', $classes), 434 ), 435 $content)), 436 $major_event,); 437 } 438 439 private function renderExtra(array $events) { 440 $extra = array(); 441 442 if ($this->getIsPreview()) { 443 $extra[] = pht('PREVIEW'); 444 } else { 445 foreach ($events as $event) { 446 if ($event->getIsEdited()) { 447 $extra[] = pht('Edited'); 448 break; 449 } 450 } 451 452 $source = $this->getContentSource(); 453 if ($source) { 454 $extra[] = id(new PhabricatorContentSourceView()) 455 ->setContentSource($source) 456 ->setUser($this->getUser()) 457 ->render(); 458 } 459 460 $date_created = null; 461 foreach ($events as $event) { 462 if ($event->getDateCreated()) { 463 if ($date_created === null) { 464 $date_created = $event->getDateCreated(); 465 } else { 466 $date_created = min($event->getDateCreated(), $date_created); 467 } 468 } 469 } 470 471 if ($date_created) { 472 $date = phabricator_datetime( 473 $date_created, 474 $this->getUser()); 475 if ($this->anchor) { 476 Javelin::initBehavior('phabricator-watch-anchor'); 477 478 $anchor = id(new PhabricatorAnchorView()) 479 ->setAnchorName($this->anchor) 480 ->render(); 481 482 $date = array( 483 $anchor, 484 phutil_tag( 485 'a', 486 array( 487 'href' => '#'.$this->anchor, 488 ), 489 $date), 490 ); 491 } 492 $extra[] = $date; 493 } 494 } 495 496 $extra = javelin_tag( 497 'span', 498 array( 499 'class' => 'phui-timeline-extra', 500 ), 501 phutil_implode_html( 502 javelin_tag( 503 'span', 504 array( 505 'aural' => false, 506 ), 507 self::DELIMITER), 508 $extra)); 509 510 return $extra; 511 } 512 513 private function getMenuItems($anchor) { 514 $xaction_phid = $this->getTransactionPHID(); 515 516 $items = array(); 517 518 if ($this->getIsEditable()) { 519 $items[] = id(new PhabricatorActionView()) 520 ->setIcon('fa-pencil') 521 ->setHref('/transactions/edit/'.$xaction_phid.'/') 522 ->setName(pht('Edit Comment')) 523 ->addSigil('transaction-edit') 524 ->setMetadata( 525 array( 526 'anchor' => $anchor, 527 )); 528 } 529 530 if ($this->getQuoteTargetID()) { 531 $ref = null; 532 if ($this->getQuoteRef()) { 533 $ref = $this->getQuoteRef(); 534 if ($anchor) { 535 $ref = $ref.'#'.$anchor; 536 } 537 } 538 539 $items[] = id(new PhabricatorActionView()) 540 ->setIcon('fa-quote-left') 541 ->setHref('#') 542 ->setName(pht('Quote')) 543 ->addSigil('transaction-quote') 544 ->setMetadata( 545 array( 546 'targetID' => $this->getQuoteTargetID(), 547 'uri' => '/transactions/quote/'.$xaction_phid.'/', 548 'ref' => $ref, 549 )); 550 551 // if there is something to quote then there is something to view raw 552 $items[] = id(new PhabricatorActionView()) 553 ->setIcon('fa-cutlery') 554 ->setHref('/transactions/raw/'.$xaction_phid.'/') 555 ->setName(pht('View Raw')) 556 ->addSigil('transaction-raw') 557 ->setMetadata( 558 array( 559 'anchor' => $anchor, 560 )); 561 562 $content_source = $this->getContentSource(); 563 $source_email = PhabricatorContentSource::SOURCE_EMAIL; 564 if ($content_source->getSource() == $source_email) { 565 $source_id = $content_source->getParam('id'); 566 if ($source_id) { 567 $items[] = id(new PhabricatorActionView()) 568 ->setIcon('fa-envelope-o') 569 ->setHref('/transactions/raw/'.$xaction_phid.'/?email') 570 ->setName(pht('View Email Body')) 571 ->addSigil('transaction-raw') 572 ->setMetadata( 573 array( 574 'anchor' => $anchor, 575 )); 576 } 577 } 578 } 579 580 if ($this->getIsRemovable()) { 581 $items[] = id(new PhabricatorActionView()) 582 ->setIcon('fa-times') 583 ->setHref('/transactions/remove/'.$xaction_phid.'/') 584 ->setName(pht('Remove Comment')) 585 ->addSigil('transaction-remove') 586 ->setMetadata( 587 array( 588 'anchor' => $anchor, 589 )); 590 591 } 592 593 if ($this->getIsEdited()) { 594 $items[] = id(new PhabricatorActionView()) 595 ->setIcon('fa-list') 596 ->setHref('/transactions/history/'.$xaction_phid.'/') 597 ->setName(pht('View Edit History')) 598 ->setWorkflow(true); 599 } 600 601 return $items; 602 } 603 604 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |