diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -264,6 +264,7 @@ 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', + 'ConpherenceTransactionRenderer' => 'applications/conpherence/ConpherenceTransactionRenderer.php', 'ConpherenceTransactionType' => 'applications/conpherence/constants/ConpherenceTransactionType.php', 'ConpherenceTransactionView' => 'applications/conpherence/view/ConpherenceTransactionView.php', 'ConpherenceUpdateActions' => 'applications/conpherence/constants/ConpherenceUpdateActions.php', @@ -2610,7 +2611,6 @@ 'PhabricatorTokensApplication' => 'applications/tokens/application/PhabricatorTokensApplication.php', 'PhabricatorTokensSettingsPanel' => 'applications/settings/panel/PhabricatorTokensSettingsPanel.php', 'PhabricatorTooltipUIExample' => 'applications/uiexample/examples/PhabricatorTooltipUIExample.php', - 'PhabricatorTransactionView' => 'view/layout/PhabricatorTransactionView.php', 'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php', 'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php', 'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php', @@ -3446,6 +3446,7 @@ 'ConpherenceDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', + 'PhabricatorMentionableInterface', 'PhabricatorDestructibleInterface', ), 'ConpherenceThreadIndexer' => 'PhabricatorSearchDocumentIndexer', @@ -6009,7 +6010,6 @@ 'PhabricatorTokensApplication' => 'PhabricatorApplication', 'PhabricatorTokensSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorTooltipUIExample' => 'PhabricatorUIExample', - 'PhabricatorTransactionView' => 'AphrontView', 'PhabricatorTransactionsApplication' => 'PhabricatorApplication', 'PhabricatorTransformedFile' => 'PhabricatorFileDAO', 'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions', diff --git a/src/applications/conpherence/ConpherenceTransactionRenderer.php b/src/applications/conpherence/ConpherenceTransactionRenderer.php new file mode 100644 --- /dev/null +++ b/src/applications/conpherence/ConpherenceTransactionRenderer.php @@ -0,0 +1,127 @@ +getTransactions(); + $oldest_transaction_id = 0; + $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1; + if (count($transactions) == $too_many) { + $last_transaction = end($transactions); + unset($transactions[$last_transaction->getID()]); + $oldest_transaction = end($transactions); + $oldest_transaction_id = $oldest_transaction->getID(); + } + $transactions = array_reverse($transactions); + $handles = $conpherence->getHandles(); + $rendered_transactions = array(); + $engine = id(new PhabricatorMarkupEngine()) + ->setViewer($user) + ->setContextObject($conpherence); + foreach ($transactions as $key => $transaction) { + if ($transaction->shouldHide()) { + unset($transactions[$key]); + continue; + } + if ($transaction->getComment()) { + $engine->addObject( + $transaction->getComment(), + PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); + } + } + $engine->process(); + // we're going to insert a dummy date marker transaction for breaks + // between days. some setup required! + $previous_transaction = null; + $date_marker_transaction = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_DATE_MARKER) + ->makeEphemeral(); + $date_marker_transaction_view = id(new ConpherenceTransactionView()) + ->setUser($user) + ->setConpherenceTransaction($date_marker_transaction) + ->setConpherenceThread($conpherence) + ->setHandles($handles) + ->setMarkupEngine($engine); + + $transaction_view_template = id(new ConpherenceTransactionView()) + ->setUser($user) + ->setConpherenceThread($conpherence) + ->setHandles($handles) + ->setMarkupEngine($engine); + + foreach ($transactions as $transaction) { + if ($previous_transaction) { + $previous_day = phabricator_format_local_time( + $previous_transaction->getDateCreated(), + $user, + 'Ymd'); + $current_day = phabricator_format_local_time( + $transaction->getDateCreated(), + $user, + 'Ymd'); + // date marker transaction time! + if ($previous_day != $current_day) { + $date_marker_transaction->setDateCreated( + $transaction->getDateCreated()); + $rendered_transactions[] = $date_marker_transaction_view->render(); + } + } + $transaction_view = id(clone $transaction_view_template) + ->setConpherenceTransaction($transaction); + if ($full_display) { + $transaction_view + ->setAnchor( + $transaction->getID(), + phabricator_time($transaction->getDateCreated(), $user)); + $transaction_view->setContentSource($transaction->getContentSource()); + $transaction_view->setShowImages(true); + } else { + $transaction_view + ->setEpoch( + $transaction->getDateCreated(), + '/'.$conpherence->getMonogram().'#'.$transaction->getID()) + ->setTimeOnly(true); + $transaction_view->setShowImages(false); + } + + $rendered_transactions[] = $transaction_view->render(); + $previous_transaction = $transaction; + } + $latest_transaction_id = $transaction->getID(); + + return array( + 'transactions' => $rendered_transactions, + 'latest_transaction' => $transaction, + 'latest_transaction_id' => $latest_transaction_id, + 'oldest_transaction_id' => $oldest_transaction_id, + ); + } + + public static function renderMessagePaneContent( + array $transactions, + $oldest_transaction_id) { + + $scrollbutton = ''; + if ($oldest_transaction_id) { + $scrollbutton = javelin_tag( + 'a', + array( + 'href' => '#', + 'mustcapture' => true, + 'sigil' => 'show-older-messages', + 'class' => 'conpherence-show-older-messages', + 'meta' => array( + 'oldest_transaction_id' => $oldest_transaction_id, + ), + ), + pht('Show Older Messages')); + } + + return hsprintf('%s%s', $scrollbutton, $transactions); + } + +} diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -408,7 +408,7 @@ $non_update = false; if ($need_transactions && $conpherence->getTransactions()) { - $data = ConpherenceTransactionView::renderTransactions( + $data = ConpherenceTransactionRenderer::renderTransactions( $user, $conpherence, !$this->getRequest()->getExists('minimal_display')); diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php --- a/src/applications/conpherence/controller/ConpherenceViewController.php +++ b/src/applications/conpherence/controller/ConpherenceViewController.php @@ -36,10 +36,10 @@ unset($write_guard); } - $data = ConpherenceTransactionView::renderTransactions( + $data = ConpherenceTransactionRenderer::renderTransactions( $user, $conpherence); - $messages = ConpherenceTransactionView::renderMessagePaneContent( + $messages = ConpherenceTransactionRenderer::renderMessagePaneContent( $data['transactions'], $data['oldest_transaction_id']); if ($before_transaction_id) { diff --git a/src/applications/conpherence/view/ConpherenceDurableColumnView.php b/src/applications/conpherence/view/ConpherenceDurableColumnView.php --- a/src/applications/conpherence/view/ConpherenceDurableColumnView.php +++ b/src/applications/conpherence/view/ConpherenceDurableColumnView.php @@ -446,11 +446,11 @@ ); } - $data = ConpherenceTransactionView::renderTransactions( + $data = ConpherenceTransactionRenderer::renderTransactions( $this->getUser(), $conpherence, $full_display = false); - $messages = ConpherenceTransactionView::renderMessagePaneContent( + $messages = ConpherenceTransactionRenderer::renderMessagePaneContent( $data['transactions'], $data['oldest_transaction_id']); diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php --- a/src/applications/conpherence/view/ConpherenceTransactionView.php +++ b/src/applications/conpherence/view/ConpherenceTransactionView.php @@ -6,15 +6,33 @@ private $conpherenceTransaction; private $handles; private $markupEngine; - private $renderAnchors = true; + private $epoch; + private $epochHref; + private $contentSource; + private $anchorName; + private $anchorText; + private $classes = array(); + private $timeOnly; private $showImages = true; - private $showContentSource = true; - public function setMarkupEngine(PhabricatorMarkupEngine $markup_engine) { - $this->markupEngine = $markup_engine; + public function setConpherenceThread(ConpherenceThread $t) { + $this->conpherenceThread = $t; + return $this; + } + + private function getConpherenceThread() { + return $this->conpherenceThread; + } + + public function setConpherenceTransaction(ConpherenceTransaction $tx) { + $this->conpherenceTransaction = $tx; return $this; } + private function getConpherenceTransaction() { + return $this->conpherenceTransaction; + } + public function setHandles(array $handles) { assert_instances_of($handles, 'PhabricatorObjectHandle'); $this->handles = $handles; @@ -25,53 +43,63 @@ return $this->handles; } - public function setConpherenceThread(ConpherenceThread $t) { - $this->conpherenceThread = $t; + public function setMarkupEngine(PhabricatorMarkupEngine $markup_engine) { + $this->markupEngine = $markup_engine; return $this; } - private function getConpherenceThread() { - return $this->conpherenceThread; + private function getMarkupEngine() { + return $this->markupEngine; } - public function setConpherenceTransaction(ConpherenceTransaction $tx) { - $this->conpherenceTransaction = $tx; + public function setEpoch($epoch, $epoch_href = null) { + $this->epoch = $epoch; + $this->epochHref = $epoch_href; return $this; } - private function getConpherenceTransaction() { - return $this->conpherenceTransaction; + public function setContentSource(PhabricatorContentSource $source) { + $this->contentSource = $source; + return $this; } - public function setShowImages($bool) { - $this->showImages = $bool; - return $this; + private function getContentSource() { + return $this->contentSource; } - private function getShowImages() { - return $this->showImages; + public function setAnchor($anchor_name, $anchor_text) { + $this->anchorName = $anchor_name; + $this->anchorText = $anchor_text; + return $this; } - public function setShowContentSource($bool) { - $this->showContentSource = $bool; + public function addClass($class) { + $this->classes[] = $class; return $this; } - private function getShowContentSource() { - return $this->showContentSource; + public function setTimeOnly($time) { + $this->timeOnly = $time; + return $this; } - public function setRenderAnchors($bool) { - $this->renderAnchors = $bool; + public function setShowImages($bool) { + $this->showImages = $bool; return $this; } - private function getRenderAnchors() { - return $this->renderAnchors; + private function getShowImages() { + return $this->showImages; } public function render() { $user = $this->getUser(); + if (!$user) { + throw new Exception(pht('Call setUser() before render()!')); + } + + // TODO - rename / condense this...! + require_celerity_resource('phabricator-transaction-view-css'); $transaction = $this->getConpherenceTransaction(); switch ($transaction->getTransactionType()) { @@ -95,31 +123,135 @@ break; } - $conpherence = $this->getConpherenceThread(); - $handles = $this->getHandles(); - $transaction->setHandles($handles); - $author = $handles[$transaction->getAuthorPHID()]; - $transaction_view = id(new PhabricatorTransactionView()) - ->setUser($user); - if ($this->getRenderAnchors()) { - $transaction_view - ->setAnchor( - $transaction->getID(), - phabricator_time($transaction->getDateCreated(), $user)); - } else { - $transaction_view - ->setEpoch( - $transaction->getDateCreated(), - '/'.$conpherence->getMonogram().'#'.$transaction->getID()) - ->setTimeOnly(true); + $info = $this->renderTransactionInfo(); + $actions = $this->renderTransactionActions(); + $image = $this->renderTransactionImage(); + $content = $this->renderTransactionContent(); + $classes = implode(' ', $this->classes); + + $transaction_id = $this->anchorName ? 'anchor-'.$this->anchorName : null; + + $header = phutil_tag_div( + 'phabricator-transaction-header grouped', + array($actions, $info)); + + return phutil_tag( + 'div', + array( + 'class' => 'phabricator-transaction-view '.$classes, + 'id' => $transaction_id, + ), + array( + $image, + phutil_tag_div('phabricator-transaction-detail grouped', + array($header, $content)), + )); + } + + private function renderTransactionInfo() { + $info = array(); + + if ($this->getContentSource()) { + $content_source = id(new PhabricatorContentSourceView()) + ->setContentSource($this->getContentSource()) + ->setUser($this->user) + ->render(); + if ($content_source) { + $info[] = $content_source; + } } - if ($this->getShowContentSource()) { - $transaction_view->setContentSource($transaction->getContentSource()); + + if ($this->epoch) { + if ($this->timeOnly) { + $epoch = phabricator_time($this->epoch, $this->user); + } else { + $epoch = phabricator_datetime($this->epoch, $this->user); + } + if ($this->epochHref) { + $epoch = phutil_tag( + 'a', + array( + 'href' => $this->epochHref, + 'class' => 'epoch-link', + ), + $epoch); + } + $info[] = $epoch; + } + + if ($this->anchorName) { + Javelin::initBehavior('phabricator-watch-anchor'); + + $anchor = id(new PhabricatorAnchorView()) + ->setAnchorName($this->anchorName) + ->render(); + + $info[] = hsprintf( + '%s%s', + $anchor, + phutil_tag( + 'a', + array( + 'href' => '#'.$this->anchorName, + 'class' => 'anchor-link', + ), + $this->anchorText)); + } + + $info = phutil_implode_html(" \xC2\xB7 ", $info); + + return phutil_tag( + 'span', + array( + 'class' => 'phabricator-transaction-info', + ), + $info); + } + + private function renderTransactionActions() { + $transaction = $this->getConpherenceTransaction(); + + switch ($transaction->getTransactionType()) { + case PhabricatorTransactions::TYPE_COMMENT: + $handles = $this->getHandles(); + $author = $handles[$transaction->getAuthorPHID()]; + $actions = array($author->renderLink()); + break; + default: + $actions = null; + break; + } + + return $actions; + } + + private function renderTransactionImage() { + $image = null; + if ($this->getShowImages()) { + $transaction = $this->getConpherenceTransaction(); + switch ($transaction->getTransactionType()) { + case PhabricatorTransactions::TYPE_COMMENT: + $handles = $this->getHandles(); + $author = $handles[$transaction->getAuthorPHID()]; + $image_uri = $author->getImageURI(); + $image = phutil_tag( + 'span', + array( + 'class' => 'phabricator-transaction-image', + 'style' => 'background-image: url('.$image_uri.');', + )); + break; + } } + return $image; + } + private function renderTransactionContent() { + $transaction = $this->getConpherenceTransaction(); $content = null; $content_class = null; $content = null; + $handles = $this->getHandles(); switch ($transaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_FILES: $content = $transaction->getTitle(); @@ -131,23 +263,20 @@ case PhabricatorTransactions::TYPE_JOIN_POLICY: case PhabricatorTransactions::TYPE_EDGE: $content = $transaction->getTitle(); - $transaction_view->addClass('conpherence-edited'); + $this->addClass('conpherence-edited'); break; case PhabricatorTransactions::TYPE_COMMENT: - $transaction_view->addClass('conpherence-comment'); + $this->addClass('conpherence-comment'); + $author = $handles[$transaction->getAuthorPHID()]; $comment = $transaction->getComment(); - $content = $this->markupEngine->getOutput( + $content = $this->getMarkupEngine()->getOutput( $comment, PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); $content_class = 'conpherence-message phabricator-remarkup'; - if ($this->getShowImages()) { - $transaction_view->setImageURI($author->getImageURI()); - } - $transaction_view->setActions(array($author->renderLink())); - break; + break; } - $transaction_view->appendChild( + $this->appendChild( phutil_tag( 'div', array( @@ -155,116 +284,9 @@ ), $content)); - return $transaction_view->render(); - } - - public static function renderTransactions( - PhabricatorUser $user, - ConpherenceThread $conpherence, - $full_display = true) { - - $transactions = $conpherence->getTransactions(); - $oldest_transaction_id = 0; - $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1; - if (count($transactions) == $too_many) { - $last_transaction = end($transactions); - unset($transactions[$last_transaction->getID()]); - $oldest_transaction = end($transactions); - $oldest_transaction_id = $oldest_transaction->getID(); - } - $transactions = array_reverse($transactions); - $handles = $conpherence->getHandles(); - $rendered_transactions = array(); - $engine = id(new PhabricatorMarkupEngine()) - ->setViewer($user) - ->setContextObject($conpherence); - foreach ($transactions as $key => $transaction) { - if ($transaction->shouldHide()) { - unset($transactions[$key]); - continue; - } - if ($transaction->getComment()) { - $engine->addObject( - $transaction->getComment(), - PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); - } - } - $engine->process(); - // we're going to insert a dummy date marker transaction for breaks - // between days. some setup required! - $previous_transaction = null; - $date_marker_transaction = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_DATE_MARKER) - ->makeEphemeral(); - $date_marker_transaction_view = id(new ConpherenceTransactionView()) - ->setUser($user) - ->setConpherenceTransaction($date_marker_transaction) - ->setConpherenceThread($conpherence) - ->setHandles($handles) - ->setShowImages($full_display) - ->setShowContentSource($full_display) - ->setRenderAnchors($full_display) - ->setMarkupEngine($engine); - foreach ($transactions as $transaction) { - if ($previous_transaction) { - $previous_day = phabricator_format_local_time( - $previous_transaction->getDateCreated(), - $user, - 'Ymd'); - $current_day = phabricator_format_local_time( - $transaction->getDateCreated(), - $user, - 'Ymd'); - // date marker transaction time! - if ($previous_day != $current_day) { - $date_marker_transaction->setDateCreated( - $transaction->getDateCreated()); - $rendered_transactions[] = $date_marker_transaction_view->render(); - } - } - $rendered_transactions[] = id(new ConpherenceTransactionView()) - ->setUser($user) - ->setConpherenceTransaction($transaction) - ->setConpherenceThread($conpherence) - ->setHandles($handles) - ->setMarkupEngine($engine) - ->setRenderAnchors($full_display) - ->setShowImages($full_display) - ->setShowContentSource($full_display) - ->render(); - $previous_transaction = $transaction; - } - $latest_transaction_id = $transaction->getID(); - - return array( - 'transactions' => $rendered_transactions, - 'latest_transaction' => $transaction, - 'latest_transaction_id' => $latest_transaction_id, - 'oldest_transaction_id' => $oldest_transaction_id, - ); - } - - public static function renderMessagePaneContent( - array $transactions, - $oldest_transaction_id) { - - $scrollbutton = ''; - if ($oldest_transaction_id) { - $scrollbutton = javelin_tag( - 'a', - array( - 'href' => '#', - 'mustcapture' => true, - 'sigil' => 'show-older-messages', - 'class' => 'conpherence-show-older-messages', - 'meta' => array( - 'oldest_transaction_id' => $oldest_transaction_id, - ), - ), - pht('Show Older Messages')); - } - - return hsprintf('%s%s', $scrollbutton, $transactions); + return phutil_tag_div( + 'phabricator-transaction-content', + $this->renderChildren()); } } diff --git a/src/view/layout/PhabricatorTransactionView.php b/src/view/layout/PhabricatorTransactionView.php deleted file mode 100644 --- a/src/view/layout/PhabricatorTransactionView.php +++ /dev/null @@ -1,179 +0,0 @@ -imageURI = $uri; - return $this; - } - - public function setActions(array $actions) { - $this->actions = $actions; - return $this; - } - - public function setEpoch($epoch, $epoch_href = null) { - $this->epoch = $epoch; - $this->epochHref = $epoch_href; - return $this; - } - - public function setContentSource(PhabricatorContentSource $source) { - $this->contentSource = $source; - return $this; - } - - public function setAnchor($anchor_name, $anchor_text) { - $this->anchorName = $anchor_name; - $this->anchorText = $anchor_text; - return $this; - } - - public function addClass($class) { - $this->classes[] = $class; - return $this; - } - - public function setIsPreview($preview) { - $this->isPreview = $preview; - return $this; - } - - public function setTimeOnly($time) { - $this->timeOnly = $time; - return $this; - } - - public function render() { - if (!$this->user) { - throw new Exception(pht('Call setUser() before render()!')); - } - - require_celerity_resource('phabricator-transaction-view-css'); - - $info = $this->renderTransactionInfo(); - $actions = $this->renderTransactionActions(); - $image = $this->renderTransactionImage(); - $content = $this->renderTransactionContent(); - $classes = implode(' ', $this->classes); - - $transaction_id = $this->anchorName ? 'anchor-'.$this->anchorName : null; - - $header = phutil_tag_div( - 'phabricator-transaction-header grouped', - array($actions, $info)); - - return phutil_tag( - 'div', - array( - 'class' => 'phabricator-transaction-view '.$classes, - 'id' => $transaction_id, - ), - array( - $image, - phutil_tag_div('phabricator-transaction-detail grouped', - array($header, $content)), - )); - - } - - private function renderTransactionInfo() { - $info = array(); - - if ($this->contentSource) { - $content_source = new PhabricatorContentSourceView(); - $content_source->setContentSource($this->contentSource); - $content_source->setUser($this->user); - $source = $content_source->render(); - if ($source) { - $info[] = $source; - } - } - - if ($this->isPreview) { - $info[] = pht('PREVIEW'); - } else if ($this->epoch) { - if ($this->timeOnly) { - $epoch = phabricator_time($this->epoch, $this->user); - } else { - $epoch = phabricator_datetime($this->epoch, $this->user); - } - if ($this->epochHref) { - $epoch = phutil_tag( - 'a', - array( - 'href' => $this->epochHref, - 'class' => 'epoch-link', - ), - $epoch); - } - $info[] = $epoch; - } - - if ($this->anchorName) { - Javelin::initBehavior('phabricator-watch-anchor'); - - $anchor = id(new PhabricatorAnchorView()) - ->setAnchorName($this->anchorName) - ->render(); - - $info[] = hsprintf( - '%s%s', - $anchor, - phutil_tag( - 'a', - array( - 'href' => '#'.$this->anchorName, - 'class' => 'anchor-link', - ), - $this->anchorText)); - } - - $info = phutil_implode_html(" \xC2\xB7 ", $info); - - return phutil_tag( - 'span', - array( - 'class' => 'phabricator-transaction-info', - ), - $info); - } - - private function renderTransactionActions() { - return $this->actions; - } - - private function renderTransactionImage() { - if ($this->imageURI) { - return phutil_tag( - 'span', - array( - 'class' => 'phabricator-transaction-image', - 'style' => 'background-image: url('.$this->imageURI.');', - )); - } else { - return null; - } - } - - private function renderTransactionContent() { - if (!$this->hasChildren()) { - return null; - } - return phutil_tag_div( - 'phabricator-transaction-content', - $this->renderChildren()); - } - -}