diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index fa17f8e105..b51268d22a 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -2179,7 +2179,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-phabricator-transaction-comment-form' => array( - 'uri' => '/res/dddc07e9/rsrc/js/application/transactions/behavior-transaction-comment-form.js', + 'uri' => '/res/3c8d3c10/rsrc/js/application/transactions/behavior-transaction-comment-form.js', 'type' => 'js', 'requires' => array( diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e0190a9f67..669bf0e0f2 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1870,6 +1870,7 @@ phutil_register_library_map(array( 'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php', 'PonderAddCommentView' => 'applications/ponder/view/PonderAddCommentView.php', 'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php', + 'PonderAnswerCommentController' => 'applications/ponder/controller/PonderAnswerCommentController.php', 'PonderAnswerEditController' => 'applications/ponder/controller/PonderAnswerEditController.php', 'PonderAnswerEditor' => 'applications/ponder/editor/PonderAnswerEditor.php', 'PonderAnswerListView' => 'applications/ponder/view/PonderAnswerListView.php', @@ -3994,6 +3995,7 @@ phutil_register_library_map(array( 4 => 'PhabricatorSubscribableInterface', 5 => 'PhabricatorTokenReceiverInterface', ), + 'PonderAnswerCommentController' => 'PonderController', 'PonderAnswerEditController' => 'PonderController', 'PonderAnswerEditor' => 'PhabricatorApplicationTransactionEditor', 'PonderAnswerListView' => 'AphrontView', diff --git a/src/applications/ponder/application/PhabricatorApplicationPonder.php b/src/applications/ponder/application/PhabricatorApplicationPonder.php index 738b947285..ad2e154407 100644 --- a/src/applications/ponder/application/PhabricatorApplicationPonder.php +++ b/src/applications/ponder/application/PhabricatorApplicationPonder.php @@ -52,6 +52,7 @@ final class PhabricatorApplicationPonder extends PhabricatorApplication { '(?:query/(?P[^/]+)/)?' => 'PonderQuestionListController', 'answer/add/' => 'PonderAnswerSaveController', 'answer/edit/(?P\d+)/' => 'PonderAnswerEditController', + 'answer/comment/(?P\d+)/' => 'PonderAnswerCommentController', 'answer/preview/' => 'PonderAnswerPreviewController', 'question/edit/(?:(?P\d+)/)?' => 'PonderQuestionEditController', 'question/preview/' => 'PonderQuestionPreviewController', diff --git a/src/applications/ponder/controller/PonderAnswerCommentController.php b/src/applications/ponder/controller/PonderAnswerCommentController.php new file mode 100644 index 0000000000..e05c319ea6 --- /dev/null +++ b/src/applications/ponder/controller/PonderAnswerCommentController.php @@ -0,0 +1,71 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + if (!$request->isFormPost()) { + return new Aphront400Response(); + } + + $answer = id(new PonderAnswerQuery()) + ->setViewer($viewer) + ->withIDs(array($this->id)) + ->executeOne(); + if (!$answer) { + return new Aphront404Response(); + } + + $is_preview = $request->isPreviewRequest(); +// $draft = PhabricatorDraft::buildFromRequest($request); + + $qid = $answer->getQuestion()->getID(); + $aid = $answer->getID(); + $view_uri = "Q{$qid}#A{$aid}"; + + $xactions = array(); + $xactions[] = id(new PonderAnswerTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new PonderAnswerTransactionComment()) + ->setContent($request->getStr('comment'))); + + $editor = id(new PonderAnswerEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect($request->isContinueRequest()) + ->setContentSourceFromRequest($request) + ->setIsPreview($is_preview); + + try { + $xactions = $editor->applyTransactions($answer, $xactions); + } catch (PhabricatorApplicationTransactionNoEffectException $ex) { + return id(new PhabricatorApplicationTransactionNoEffectResponse()) + ->setCancelURI($view_uri) + ->setException($ex); + } + +// if ($draft) { +// $draft->replaceOrDelete(); +// } + + if ($request->isAjax()) { + return id(new PhabricatorApplicationTransactionResponse()) + ->setViewer($viewer) + ->setTransactions($xactions) + ->setIsPreview($is_preview) + ->setAnchorOffset($request->getStr('anchor')); + } else { + return id(new AphrontRedirectResponse()) + ->setURI($view_uri); + } + } + +} diff --git a/src/applications/ponder/controller/PonderQuestionStatusController.php b/src/applications/ponder/controller/PonderQuestionStatusController.php index 0b5ccc65cf..2b92970442 100644 --- a/src/applications/ponder/controller/PonderQuestionStatusController.php +++ b/src/applications/ponder/controller/PonderQuestionStatusController.php @@ -14,13 +14,23 @@ final class PonderQuestionStatusController public function processRequest() { $request = $this->getRequest(); - $user = $request->getUser(); + $viewer = $request->getUser(); - $question = id(new PonderQuestion())->load($this->id); + $question = id(new PonderQuestionQuery()) + ->setViewer($viewer) + ->withIDs(array($this->id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); if (!$question) { return new Aphront404Response(); } + // TODO: Use transactions. + switch ($this->status) { case 'open': $question->setStatus(PonderQuestionStatus::STATUS_OPEN); diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php index 93d4065a4e..475d6c4634 100644 --- a/src/applications/ponder/controller/PonderQuestionViewController.php +++ b/src/applications/ponder/controller/PonderQuestionViewController.php @@ -209,6 +209,7 @@ final class PonderQuestionViewController extends PonderController { foreach ($answers as $answer) { $author_phid = $answer->getAuthorPHID(); $xactions = idx($xaction_groups, $answer->getPHID(), array()); + $id = $answer->getID(); $out[] = phutil_tag('br'); $out[] = phutil_tag('br'); @@ -218,13 +219,17 @@ final class PonderQuestionViewController extends PonderController { $out[] = $this->buildAnswerActions($answer); $out[] = $this->buildAnswerProperties($answer); + $out[] = id(new PhabricatorApplicationTransactionView()) ->setUser($viewer) ->setTransactions($xactions) ->setMarkupEngine($engine); - // TODO: Add comment form - + $out[] = id(new PhabricatorApplicationTransactionCommentView()) + ->setUser($viewer) + ->setShowPreview(false) + ->setAction($this->getApplicationURI("/answer/comment/{$id}/")) + ->setSubmitButtonName(pht('Comment')); } $out[] = phutil_tag('br'); diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php index 4eb469be2a..167b0a31e6 100644 --- a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php @@ -16,6 +16,16 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView { private $commentID; private $draft; private $requestURI; + private $showPreview = true; + + public function setShowPreview($show_preview) { + $this->showPreview = $show_preview; + return $this; + } + + public function getShowPreview() { + return $this->showPreview; + } public function setRequestURI(PhutilURI $request_uri) { $this->requestURI = $request_uri; @@ -77,7 +87,11 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView { $comment = $this->renderCommentPanel(); - $preview = $this->renderPreviewPanel(); + if ($this->getShowPreview()) { + $preview = $this->renderPreviewPanel(); + } else { + $preview = null; + } Javelin::initBehavior( 'phabricator-transaction-comment-form', @@ -92,8 +106,12 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView { 'savingString' => pht('Saving Draft...'), 'draftString' => pht('Saved Draft'), + 'showPreview' => $this->getShowPreview(), + 'actionURI' => $this->getAction(), - 'draftKey' => $this->getDraft()->getDraftKey(), + 'draftKey' => $this->getDraft() + ? $this->getDraft()->getDraftKey() + : null, )); return array($comment, $preview); diff --git a/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js b/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js index 88558ce79a..93f5da08ad 100644 --- a/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js +++ b/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js @@ -14,18 +14,24 @@ JX.behavior('phabricator-transaction-comment-form', function(config) { JX.DOM.listen(form, 'willSubmit', null, function (e) { e.kill(); - var preview = JX.$(config.panelID); - preview.style.opacity = 0.5; + if (config.showPreview) { + var preview = JX.$(config.panelID); + preview.style.opacity = 0.5; + } }); + JX.DOM.listen(form, 'willClear', null, function(e) { JX.$(config.commentID).value = ''; - var preview = JX.$(config.panelID); - new JX.FX(preview) - .setDuration(500) - .then(function () { - new JX.FX(preview).setDuration(1000).start({opacity: [0, 1]}); - }) - .start({opacity: [0.5, 0]}); + + if (config.showPreview) { + var preview = JX.$(config.panelID); + new JX.FX(preview) + .setDuration(500) + .then(function () { + new JX.FX(preview).setDuration(1000).start({opacity: [0, 1]}); + }) + .start({opacity: [0.5, 0]}); + } }); var getdata = function() { @@ -55,18 +61,20 @@ JX.behavior('phabricator-transaction-comment-form', function(config) { } }; - var request = new JX.PhabricatorShapedRequest( - config.actionURI, - onresponse, - getdata); - var trigger = JX.bind(request, request.trigger); - JX.DOM.listen(form, 'keydown', null, trigger); - var always_trigger = function() { - new JX.Request(config.actionURI, onresponse) - .setData(getdata()) - .send(); - }; - JX.DOM.listen(form, 'shouldRefresh', null, always_trigger); + if (config.showPreview) { + var request = new JX.PhabricatorShapedRequest( + config.actionURI, + onresponse, + getdata); + var trigger = JX.bind(request, request.trigger); + JX.DOM.listen(form, 'keydown', null, trigger); + var always_trigger = function() { + new JX.Request(config.actionURI, onresponse) + .setData(getdata()) + .send(); + }; + JX.DOM.listen(form, 'shouldRefresh', null, always_trigger); - request.start(); + request.start(); + } });