diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index ceaed7a676..48e6ef848e 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1026,7 +1026,7 @@ celerity_register_resource_map(array( ), 'phabricator-feed-css' => array( - 'uri' => '/res/617811ab/rsrc/css/application/feed/feed.css', + 'uri' => '/res/32e5879b/rsrc/css/application/feed/feed.css', 'type' => 'css', 'requires' => array( diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 9dbea838e9..6f1284e26f 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -338,14 +338,17 @@ phutil_register_library_map(array( 'PhabricatorEmailLoginController' => 'applications/auth/controller/email', 'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken', 'PhabricatorEnv' => 'infrastructure/env', + 'PhabricatorFeedConstants' => 'applications/feed/constants/base', 'PhabricatorFeedController' => 'applications/feed/controller/base', 'PhabricatorFeedDAO' => 'applications/feed/storage/base', 'PhabricatorFeedQuery' => 'applications/feed/query', 'PhabricatorFeedStory' => 'applications/feed/story/base', 'PhabricatorFeedStoryData' => 'applications/feed/storage/story', + 'PhabricatorFeedStoryDifferential' => 'applications/feed/story/differential', 'PhabricatorFeedStoryPublisher' => 'applications/feed/publisher', 'PhabricatorFeedStoryReference' => 'applications/feed/storage/storyreference', 'PhabricatorFeedStoryStatus' => 'applications/feed/story/status', + 'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/story', 'PhabricatorFeedStoryUnknown' => 'applications/feed/story/unknown', 'PhabricatorFeedStoryView' => 'applications/feed/view/story', 'PhabricatorFeedStreamController' => 'applications/feed/controller/stream', @@ -857,8 +860,10 @@ phutil_register_library_map(array( 'PhabricatorFeedController' => 'PhabricatorController', 'PhabricatorFeedDAO' => 'PhabricatorLiskDAO', 'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO', + 'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory', 'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO', 'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory', + 'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants', 'PhabricatorFeedStoryUnknown' => 'PhabricatorFeedStory', 'PhabricatorFeedStoryView' => 'PhabricatorFeedView', 'PhabricatorFeedStreamController' => 'PhabricatorFeedController', diff --git a/src/applications/differential/editor/comment/DifferentialCommentEditor.php b/src/applications/differential/editor/comment/DifferentialCommentEditor.php index be49a064a0..1834b4c9ef 100644 --- a/src/applications/differential/editor/comment/DifferentialCommentEditor.php +++ b/src/applications/differential/editor/comment/DifferentialCommentEditor.php @@ -411,6 +411,20 @@ class DifferentialCommentEditor { id(new PhabricatorTimelineEvent('difx', $event_data)) ->recordEvent(); + // TODO: Move to a daemon? + id(new PhabricatorFeedStoryPublisher()) + ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_DIFFERENTIAL) + ->setStoryData($event_data) + ->setStoryTime(time()) + ->setStoryAuthorPHID($this->actorPHID) + ->setRelatedPHIDs( + array( + $revision->getPHID(), + $this->actorPHID, + $revision->getAuthorPHID(), + )) + ->publish(); + // TODO: Move to a daemon? PhabricatorSearchDifferentialIndexer::indexRevision($revision); diff --git a/src/applications/differential/editor/comment/__init__.php b/src/applications/differential/editor/comment/__init__.php index 74deebcb49..6dcae1bae7 100644 --- a/src/applications/differential/editor/comment/__init__.php +++ b/src/applications/differential/editor/comment/__init__.php @@ -14,6 +14,8 @@ phutil_require_module('phabricator', 'applications/differential/parser/markup'); phutil_require_module('phabricator', 'applications/differential/storage/changeset'); phutil_require_module('phabricator', 'applications/differential/storage/comment'); phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment'); +phutil_require_module('phabricator', 'applications/feed/constants/story'); +phutil_require_module('phabricator', 'applications/feed/publisher'); phutil_require_module('phabricator', 'applications/herald/storage/transcript/base'); phutil_require_module('phabricator', 'applications/phid/handle/data'); phutil_require_module('phabricator', 'applications/search/index/indexer/differential'); diff --git a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php index 9b9e5b554c..a669d5fe69 100644 --- a/src/applications/differential/editor/revision/DifferentialRevisionEditor.php +++ b/src/applications/differential/editor/revision/DifferentialRevisionEditor.php @@ -375,6 +375,18 @@ class DifferentialRevisionEditor { id(new PhabricatorTimelineEvent('difx', $event_data)) ->recordEvent(); + id(new PhabricatorFeedStoryPublisher()) + ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_DIFFERENTIAL) + ->setStoryData($event_data) + ->setStoryTime(time()) + ->setStoryAuthorPHID($revision->getAuthorPHID()) + ->setRelatedPHIDs( + array( + $revision->getPHID(), + $revision->getAuthorPHID(), + )) + ->publish(); + // TODO // $revision->saveTransaction(); diff --git a/src/applications/differential/editor/revision/__init__.php b/src/applications/differential/editor/revision/__init__.php index 7cb47b118b..038d9759d3 100644 --- a/src/applications/differential/editor/revision/__init__.php +++ b/src/applications/differential/editor/revision/__init__.php @@ -12,6 +12,8 @@ phutil_require_module('phabricator', 'applications/differential/mail/ccwelcome') phutil_require_module('phabricator', 'applications/differential/mail/newdiff'); phutil_require_module('phabricator', 'applications/differential/storage/comment'); phutil_require_module('phabricator', 'applications/differential/storage/revision'); +phutil_require_module('phabricator', 'applications/feed/constants/story'); +phutil_require_module('phabricator', 'applications/feed/publisher'); phutil_require_module('phabricator', 'applications/herald/adapter/differential'); phutil_require_module('phabricator', 'applications/herald/engine/engine'); phutil_require_module('phabricator', 'applications/herald/storage/transcript/base'); diff --git a/src/applications/feed/constants/base/PhabricatorFeedConstants.php b/src/applications/feed/constants/base/PhabricatorFeedConstants.php new file mode 100644 index 0000000000..79f1eab938 --- /dev/null +++ b/src/applications/feed/constants/base/PhabricatorFeedConstants.php @@ -0,0 +1,21 @@ +isFormPost()) { $story = id(new PhabricatorFeedStoryPublisher()) ->setRelatedPHIDs(array($viewer->getPHID())) - ->setStoryType('PhabricatorFeedStoryStatus') + ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_STATUS) ->setStoryTime(time()) ->setStoryAuthorPHID($viewer->getPHID()) ->setStoryData( diff --git a/src/applications/feed/controller/stream/__init__.php b/src/applications/feed/controller/stream/__init__.php index 612ba97fbc..78489305b4 100644 --- a/src/applications/feed/controller/stream/__init__.php +++ b/src/applications/feed/controller/stream/__init__.php @@ -7,6 +7,7 @@ phutil_require_module('phabricator', 'aphront/response/redirect'); +phutil_require_module('phabricator', 'applications/feed/constants/story'); phutil_require_module('phabricator', 'applications/feed/controller/base'); phutil_require_module('phabricator', 'applications/feed/publisher'); phutil_require_module('phabricator', 'applications/feed/query'); diff --git a/src/applications/feed/publisher/PhabricatorFeedStoryPublisher.php b/src/applications/feed/publisher/PhabricatorFeedStoryPublisher.php index a5c206209c..6f5d541ed6 100644 --- a/src/applications/feed/publisher/PhabricatorFeedStoryPublisher.php +++ b/src/applications/feed/publisher/PhabricatorFeedStoryPublisher.php @@ -71,7 +71,7 @@ final class PhabricatorFeedStoryPublisher { $sql = array(); $conn = $ref->establishConnection('w'); - foreach ($this->relatedPHIDs as $phid) { + foreach (array_unique($this->relatedPHIDs) as $phid) { $sql[] = qsprintf( $conn, '(%s, %s)', diff --git a/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php b/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php new file mode 100644 index 0000000000..83395108ad --- /dev/null +++ b/src/applications/feed/story/differential/PhabricatorFeedStoryDifferential.php @@ -0,0 +1,86 @@ +getStoryData(); + return array( + $this->getStoryData()->getAuthorPHID(), + $data->getValue('revision_phid'), + $data->getValue('revision_author_phid'), + ); + } + + public function getRequiredObjectPHIDs() { + return array( + $this->getStoryData()->getAuthorPHID(), + ); + } + + public function renderView() { + $data = $this->getStoryData(); + + $handles = $this->getHandles(); + $author_phid = $data->getAuthorPHID(); + + $objects = $this->getObjects(); + + $view = new PhabricatorFeedStoryView(); + + $revision_phid = $data->getValue('revision_phid'); + + $action = $data->getValue('action'); + $verb = DifferentialAction::getActionPastTenseVerb($action); + + $view->setTitle( + ''.$handles[$author_phid]->renderLink().''. + ' '.$verb.' '. + ''.$handles[$revision_phid]->renderLink().'.'); + $view->setEpoch($data->getEpoch()); + + $action = $data->getValue('action'); + switch ($action) { + case DifferentialAction::ACTION_CREATE: + case DifferentialAction::ACTION_COMMIT: + $full_size = true; + break; + default: + $full_size = false; + break; + } + + if ($full_size) { + if (!empty($objects[$author_phid])) { + $image_phid = $objects[$author_phid]->getProfileImagePHID(); + $image_uri = PhabricatorFileURI::getViewURIForPHID($image_phid); + $view->setImage($image_uri); + } + + $content = phutil_escape_html($data->getValue('feedback_content')); + $content = str_replace("\n", '
', $content); + + $view->appendChild($content); + } else { + $view->setOneLineStory(true); + } + + return $view; + } + +} diff --git a/src/applications/feed/story/differential/__init__.php b/src/applications/feed/story/differential/__init__.php new file mode 100644 index 0000000000..93cc715499 --- /dev/null +++ b/src/applications/feed/story/differential/__init__.php @@ -0,0 +1,17 @@ +viewer = $viewer; return $this; @@ -44,6 +46,11 @@ class PhabricatorFeedStoryView extends PhabricatorFeedView { return $this; } + public function setOneLineStory($one_line) { + $this->oneLine = $one_line; + return $this; + } + public function render() { $head = phutil_render_tag( @@ -53,29 +60,34 @@ class PhabricatorFeedStoryView extends PhabricatorFeedView { ), nonempty($this->title, 'Untitled Story')); - $body = phutil_render_tag( - 'div', - array( - 'class' => 'phabricator-feed-story-body', - ), - $this->renderChildren()); - - if ($this->epoch) { - $foot = phabricator_datetime($this->epoch, $this->viewer); - } else { - $foot = ''; - } - - $foot = phutil_render_tag( - 'div', - array( - 'class' => 'phabricator-feed-story-foot', - ), - $foot); - + $body = null; + $foot = null; $image_style = null; - if ($this->image) { - $image_style = 'background-image: url('.$this->image.')'; + + if (!$this->oneLine) { + $body = phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-feed-story-body', + ), + $this->renderChildren()); + + if ($this->epoch) { + $foot = phabricator_datetime($this->epoch, $this->viewer); + } else { + $foot = ''; + } + + $foot = phutil_render_tag( + 'div', + array( + 'class' => 'phabricator-feed-story-foot', + ), + $foot); + + if ($this->image) { + $image_style = 'background-image: url('.$this->image.')'; + } } require_celerity_resource('phabricator-feed-css'); @@ -83,7 +95,9 @@ class PhabricatorFeedStoryView extends PhabricatorFeedView { return phutil_render_tag( 'div', array( - 'class' => 'phabricator-feed-story', + 'class' => $this->oneLine + ? 'phabricator-feed-story phabricator-feed-story-one-line' + : 'phabricator-feed-story', 'style' => $image_style, ), $head.$body.$foot); diff --git a/webroot/rsrc/css/application/feed/feed.css b/webroot/rsrc/css/application/feed/feed.css index 2ad5dfad84..089357f802 100644 --- a/webroot/rsrc/css/application/feed/feed.css +++ b/webroot/rsrc/css/application/feed/feed.css @@ -6,6 +6,13 @@ padding-left: 64px; margin: .5em 0 1em; background: 5px 2px no-repeat; + min-height: 64px; +} + +.phabricator-feed-story-one-line { + min-height: 0; + font-size: 11px; + color: #444444; } .phabricator-feed-story-head {