diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -126,7 +126,7 @@ 'rsrc/css/phui/phui-box.css' => 'a5bb366d', 'rsrc/css/phui/phui-button.css' => '16020a60', 'rsrc/css/phui/phui-crumbs-view.css' => '414406b5', - 'rsrc/css/phui/phui-document-pro.css' => '4f2b42e3', + 'rsrc/css/phui/phui-document-pro.css' => '7f3009ce', 'rsrc/css/phui/phui-document.css' => 'f841ad0a', 'rsrc/css/phui/phui-feed-story.css' => 'b7b26d23', 'rsrc/css/phui/phui-fontkit.css' => 'c9d63950', @@ -781,7 +781,7 @@ 'phui-calendar-month-css' => '476be7e0', 'phui-crumbs-view-css' => '414406b5', 'phui-document-view-css' => 'f841ad0a', - 'phui-document-view-pro-css' => '4f2b42e3', + 'phui-document-view-pro-css' => '7f3009ce', 'phui-feed-story-css' => 'b7b26d23', 'phui-font-icon-base-css' => 'ecbbb4c2', 'phui-fontkit-css' => 'c9d63950', diff --git a/resources/sql/autopatches/20151109.phame.post.comments.1.sql b/resources/sql/autopatches/20151109.phame.post.comments.1.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20151109.phame.post.comments.1.sql @@ -0,0 +1,18 @@ +CREATE TABLE {$NAMESPACE}_phame.phame_posttransaction_comment ( + id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + phid VARCHAR(64) NOT NULL, + transactionPHID VARCHAR(64), + authorPHID VARCHAR(64) NOT NULL, + viewPolicy VARCHAR(64) NOT NULL, + editPolicy VARCHAR(64) NOT NULL, + commentVersion INT UNSIGNED NOT NULL, + content LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, + contentSource LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}, + isDeleted BOOL NOT NULL, + dateCreated INT UNSIGNED NOT NULL, + dateModified INT UNSIGNED NOT NULL, + + UNIQUE KEY `key_phid` (phid), + UNIQUE KEY `key_version` (transactionPHID, commentVersion) + +) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT}; 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 @@ -3273,6 +3273,7 @@ 'PhameCreatePostConduitAPIMethod' => 'applications/phame/conduit/PhameCreatePostConduitAPIMethod.php', 'PhameDAO' => 'applications/phame/storage/PhameDAO.php', 'PhamePost' => 'applications/phame/storage/PhamePost.php', + 'PhamePostCommentController' => 'applications/phame/controller/post/PhamePostCommentController.php', 'PhamePostController' => 'applications/phame/controller/post/PhamePostController.php', 'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php', 'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php', @@ -3287,6 +3288,7 @@ 'PhamePostReplyHandler' => 'applications/phame/mail/PhamePostReplyHandler.php', 'PhamePostSearchEngine' => 'applications/phame/query/PhamePostSearchEngine.php', 'PhamePostTransaction' => 'applications/phame/storage/PhamePostTransaction.php', + 'PhamePostTransactionComment' => 'applications/phame/storage/PhamePostTransactionComment.php', 'PhamePostTransactionQuery' => 'applications/phame/query/PhamePostTransactionQuery.php', 'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php', 'PhamePostView' => 'applications/phame/view/PhamePostView.php', @@ -7552,6 +7554,7 @@ 'PhabricatorSubscribableInterface', 'PhabricatorTokenReceiverInterface', ), + 'PhamePostCommentController' => 'PhamePostController', 'PhamePostController' => 'PhameController', 'PhamePostDeleteController' => 'PhamePostController', 'PhamePostEditController' => 'PhamePostController', @@ -7566,6 +7569,7 @@ 'PhamePostReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'PhamePostSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhamePostTransaction' => 'PhabricatorApplicationTransaction', + 'PhamePostTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhamePostTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhamePostUnpublishController' => 'PhamePostController', 'PhamePostView' => 'AphrontView', diff --git a/src/applications/phame/application/PhabricatorPhameApplication.php b/src/applications/phame/application/PhabricatorPhameApplication.php --- a/src/applications/phame/application/PhabricatorPhameApplication.php +++ b/src/applications/phame/application/PhabricatorPhameApplication.php @@ -54,6 +54,7 @@ 'framed/(?P<id>\d+)/' => 'PhamePostFramedController', 'new/' => 'PhamePostNewController', 'move/(?P<id>\d+)/' => 'PhamePostNewController', + 'comment/(?P<id>[1-9]\d*)/' => 'PhamePostCommentController', ), 'blog/' => array( '(?:(?P<filter>user|all)/)?' => 'PhameBlogListController', diff --git a/src/applications/phame/controller/post/PhamePostCommentController.php b/src/applications/phame/controller/post/PhamePostCommentController.php new file mode 100644 --- /dev/null +++ b/src/applications/phame/controller/post/PhamePostCommentController.php @@ -0,0 +1,63 @@ +<?php + +final class PhamePostCommentController + extends PhamePostController { + + public function handleRequest(AphrontRequest $request) { + $viewer = $request->getViewer(); + $id = $request->getURIData('id'); + + if (!$request->isFormPost()) { + return new Aphront400Response(); + } + + $post = id(new PhamePostQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + if (!$post) { + return new Aphront404Response(); + } + + $is_preview = $request->isPreviewRequest(); + $draft = PhabricatorDraft::buildFromRequest($request); + + $view_uri = $this->getApplicationURI('post/view/'.$post->getID().'/'); + + $xactions = array(); + $xactions[] = id(new PhamePostTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new PhamePostTransactionComment()) + ->setContent($request->getStr('comment'))); + + $editor = id(new PhamePostEditor()) + ->setActor($viewer) + ->setContinueOnNoEffect($request->isContinueRequest()) + ->setContentSourceFromRequest($request) + ->setIsPreview($is_preview); + + try { + $xactions = $editor->applyTransactions($post, $xactions); + } catch (PhabricatorApplicationTransactionNoEffectException $ex) { + return id(new PhabricatorApplicationTransactionNoEffectResponse()) + ->setCancelURI($view_uri) + ->setException($ex); + } + + if ($draft) { + $draft->replaceOrDelete(); + } + + if ($request->isAjax() && $is_preview) { + return id(new PhabricatorApplicationTransactionResponse()) + ->setViewer($viewer) + ->setTransactions($xactions) + ->setIsPreview($is_preview); + } else { + return id(new AphrontRedirectResponse()) + ->setURI($view_uri); + } + } + +} diff --git a/src/applications/phame/controller/post/PhamePostViewController.php b/src/applications/phame/controller/post/PhamePostViewController.php --- a/src/applications/phame/controller/post/PhamePostViewController.php +++ b/src/applications/phame/controller/post/PhamePostViewController.php @@ -76,13 +76,24 @@ ), $engine->getOutput($post, PhamePost::MARKUP_FIELD_BODY))); + $timeline = $this->buildTransactionTimeline( + $post, + id(new PhamePostTransactionQuery()) + ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))); + $timeline = phutil_tag_div('phui-document-view-pro-box', $timeline); + + $add_comment = $this->buildCommentForm($post); + return $this->newPage() ->setTitle($post->getTitle()) ->addClass('pro-white-background') + ->setPageObjectPHIDs(array($post->getPHID())) ->setCrumbs($crumbs) ->appendChild( array( $document, + $timeline, + $add_comment, )); } @@ -192,4 +203,27 @@ return $properties; } + private function buildCommentForm(PhamePost $post) { + $viewer = $this->getViewer(); + + $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); + + $add_comment_header = $is_serious + ? pht('Add Comment') + : pht('Derp Text'); + + $draft = PhabricatorDraft::newFromUserAndKey( + $viewer, $post->getPHID()); + + $box = id(new PhabricatorApplicationTransactionCommentView()) + ->setUser($viewer) + ->setObjectPHID($post->getPHID()) + ->setDraft($draft) + ->setHeaderText($add_comment_header) + ->setAction($this->getApplicationURI('post/comment/'.$post->getID().'/')) + ->setSubmitButtonName(pht('Add Comment')); + + return phutil_tag_div('phui-document-view-pro-box', $box); + } + } diff --git a/src/applications/phame/editor/PhamePostEditor.php b/src/applications/phame/editor/PhamePostEditor.php --- a/src/applications/phame/editor/PhamePostEditor.php +++ b/src/applications/phame/editor/PhamePostEditor.php @@ -18,6 +18,7 @@ $types[] = PhamePostTransaction::TYPE_PHAME_TITLE; $types[] = PhamePostTransaction::TYPE_BODY; $types[] = PhamePostTransaction::TYPE_VISIBILITY; + $types[] = PhabricatorTransactions::TYPE_COMMENT; return $types; } diff --git a/src/applications/phame/storage/PhamePostTransaction.php b/src/applications/phame/storage/PhamePostTransaction.php --- a/src/applications/phame/storage/PhamePostTransaction.php +++ b/src/applications/phame/storage/PhamePostTransaction.php @@ -20,6 +20,10 @@ return PhabricatorPhamePostPHIDType::TYPECONST; } + public function getApplicationTransactionCommentObject() { + return new PhamePostTransactionComment(); + } + public function getRemarkupBlocks() { $blocks = parent::getRemarkupBlocks(); diff --git a/src/applications/phame/storage/PhamePostTransactionComment.php b/src/applications/phame/storage/PhamePostTransactionComment.php new file mode 100644 --- /dev/null +++ b/src/applications/phame/storage/PhamePostTransactionComment.php @@ -0,0 +1,10 @@ +<?php + +final class PhamePostTransactionComment + extends PhabricatorApplicationTransactionComment { + + public function getApplicationTransactionObject() { + return new PhamePostTransaction(); + } + +} diff --git a/webroot/rsrc/css/phui/phui-document-pro.css b/webroot/rsrc/css/phui/phui-document-pro.css --- a/webroot/rsrc/css/phui/phui-document-pro.css +++ b/webroot/rsrc/css/phui/phui-document-pro.css @@ -112,3 +112,64 @@ .phui-document-view-pro .phui-info-view { margin: 16px 0 0 0; } + + + + +.phui-document-view-pro-box .phui-timeline-view { + padding: 0; + background: none; +} + +.phui-document-view-pro-box .phui-timeline-image { + border-radius: 25px; +} + +.phui-document-view-pro-box .phui-timeline-wedge { + display: none; +} + +.phui-document-view-pro-box .phui-timeline-major-event .phui-timeline-group { + border: none; +} + +.phui-document-view-pro-box .phui-timeline-major-event .phui-timeline-content { + border: none; +} + +.device-desktop .phui-document-view-pro-box + .phui-timeline-event-view.phui-timeline-minor-event { + margin-left: 62px; +} + +.phui-document-view-pro-box .phui-timeline-title { + border-radius: 3px; + background-color: {$lightgreybackground}; +} + +.phui-document-view-pro-box .phui-timeline-title-with-icon { + padding-left: 12px; +} + +.phui-document-view-pro-box .phui-timeline-icon-fill { + display: none; +} + +.phui-document-view-pro-box .phui-timeline-major-event .phui-timeline-content + .phui-timeline-core-content { + padding-bottom: 24px; +} + +.phui-document-view-pro-box .phui-object-box { + background-color: {$lightgreybackground}; + border: none; + margin: 0; +} + +.phui-document-view-pro-box .phui-object-box .phui-form-view { + padding-bottom: 0; +} + +.phui-document-view-pro-box .phui-object-box .remarkup-assist-textarea { + height: 9em; +}