diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index a686265085..8899a965fe 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -2235,7 +2235,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-pholio-mock-view' => array( - 'uri' => '/res/014eb2bd/rsrc/js/application/pholio/behavior-pholio-mock-view.js', + 'uri' => '/res/415cd66a/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 'type' => 'js', 'requires' => array( @@ -3806,7 +3806,7 @@ celerity_register_resource_map(array( ), 'phui-feed-story-css' => array( - 'uri' => '/res/253ac568/rsrc/css/phui/phui-feed-story.css', + 'uri' => '/res/7960f59a/rsrc/css/phui/phui-feed-story.css', 'type' => 'css', 'requires' => array( diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index d2fd18908c..ec6447b6fb 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1087,6 +1087,7 @@ phutil_register_library_map(array( 'PhabricatorFeedConstants' => 'applications/feed/constants/PhabricatorFeedConstants.php', 'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php', 'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php', + 'PhabricatorFeedDetailController' => 'applications/feed/controller/PhabricatorFeedDetailController.php', 'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php', 'PhabricatorFeedManagementRepublishWorkflow' => 'applications/feed/management/PhabricatorFeedManagementRepublishWorkflow.php', 'PhabricatorFeedManagementWorkflow' => 'applications/feed/management/PhabricatorFeedManagementWorkflow.php', @@ -3039,6 +3040,7 @@ phutil_register_library_map(array( 'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorFeedController' => 'PhabricatorController', 'PhabricatorFeedDAO' => 'PhabricatorLiskDAO', + 'PhabricatorFeedDetailController' => 'PhabricatorFeedController', 'PhabricatorFeedMainController' => 'PhabricatorFeedController', 'PhabricatorFeedManagementRepublishWorkflow' => 'PhabricatorFeedManagementWorkflow', 'PhabricatorFeedManagementWorkflow' => 'PhutilArgumentWorkflow', diff --git a/src/applications/feed/application/PhabricatorApplicationFeed.php b/src/applications/feed/application/PhabricatorApplicationFeed.php index f83b7e0aed..193fdd5db3 100644 --- a/src/applications/feed/application/PhabricatorApplicationFeed.php +++ b/src/applications/feed/application/PhabricatorApplicationFeed.php @@ -22,6 +22,7 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication { return array( '/feed/' => array( 'public/' => 'PhabricatorFeedPublicStreamController', + '(?P\d+)/' => 'PhabricatorFeedDetailController', '(?:(?P[^/]+)/)?' => 'PhabricatorFeedMainController', ), ); diff --git a/src/applications/feed/controller/PhabricatorFeedDetailController.php b/src/applications/feed/controller/PhabricatorFeedDetailController.php new file mode 100644 index 0000000000..aaa9278e96 --- /dev/null +++ b/src/applications/feed/controller/PhabricatorFeedDetailController.php @@ -0,0 +1,52 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $story = id(new PhabricatorFeedQuery()) + ->setViewer($user) + ->withChronologicalKeys(array($this->id)) + ->executeOne(); + if (!$story) { + return new Aphront404Response(); + } + + $feed = array($story); + $builder = new PhabricatorFeedBuilder($feed); + $builder->setUser($user); + $feed_view = $builder->buildView(); + + $title = pht('Story'); + + $feed_view = hsprintf( + '
%s
', + $feed_view); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName($title)); + + + return $this->buildApplicationPage( + array( + $crumbs, + $feed_view, + ), + array( + 'title' => $title, + 'device' => true, + 'dust' => true, + )); + } + +} diff --git a/src/applications/feed/story/PhabricatorFeedStory.php b/src/applications/feed/story/PhabricatorFeedStory.php index f739781194..5b9ddd594e 100644 --- a/src/applications/feed/story/PhabricatorFeedStory.php +++ b/src/applications/feed/story/PhabricatorFeedStory.php @@ -258,6 +258,13 @@ abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface { return array(); } + protected function newStoryView() { + return id(new PHUIFeedStoryView()) + ->setChronologicalKey($this->getChronologicalKey()) + ->setEpoch($this->getEpoch()) + ->setViewed($this->getHasViewed()); + } + /* -( PhabricatorPolicyInterface Implementation )-------------------------- */ diff --git a/src/applications/feed/story/PhabricatorFeedStoryAudit.php b/src/applications/feed/story/PhabricatorFeedStoryAudit.php index 7f7ce0ccff..5dd3051290 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryAudit.php +++ b/src/applications/feed/story/PhabricatorFeedStoryAudit.php @@ -10,7 +10,7 @@ final class PhabricatorFeedStoryAudit extends PhabricatorFeedStory { $author_phid = $this->getAuthorPHID(); $commit_phid = $this->getPrimaryObjectPHID(); - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('audit-dark'); $action = $this->getValue('action'); @@ -22,8 +22,6 @@ final class PhabricatorFeedStoryAudit extends PhabricatorFeedStory { $verb, $this->linkTo($commit_phid))); - $view->setEpoch($this->getEpoch()); - $comments = $this->getValue('content'); $view->setImage($this->getHandle($author_phid)->getImageURI()); diff --git a/src/applications/feed/story/PhabricatorFeedStoryCommit.php b/src/applications/feed/story/PhabricatorFeedStoryCommit.php index 1d97516b31..7c99682089 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryCommit.php +++ b/src/applications/feed/story/PhabricatorFeedStoryCommit.php @@ -49,11 +49,10 @@ final class PhabricatorFeedStoryCommit extends PhabricatorFeedStory { $commit); } - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('differential-dark'); $view->setTitle($title); - $view->setEpoch($data->getEpoch()); if ($data->getValue('authorPHID')) { $view->setImage($this->getHandle($data->getAuthorPHID())->getImageURI()); diff --git a/src/applications/feed/story/PhabricatorFeedStoryDifferential.php b/src/applications/feed/story/PhabricatorFeedStoryDifferential.php index 368d8668f4..fce311b4bc 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryDifferential.php +++ b/src/applications/feed/story/PhabricatorFeedStoryDifferential.php @@ -9,13 +9,11 @@ final class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory { public function renderView() { $data = $this->getStoryData(); - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('differential-dark'); - $view->setViewed($this->getHasViewed()); $line = $this->getLineForData($data); $view->setTitle($line); - $view->setEpoch($data->getEpoch()); $href = $this->getHandle($data->getValue('revision_phid'))->getURI(); $view->setHref($href); diff --git a/src/applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php b/src/applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php index f71e12f352..74143babc9 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php +++ b/src/applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php @@ -54,10 +54,8 @@ final class PhabricatorFeedStoryDifferentialAggregate break; } - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('differential-dark'); - $view->setEpoch($this->getEpoch()); - $view->setViewed($this->getHasViewed()); $view->setTitle($title); $href = $this->getHandle($data->getValue('revision_phid'))->getURI(); diff --git a/src/applications/feed/story/PhabricatorFeedStoryManiphest.php b/src/applications/feed/story/PhabricatorFeedStoryManiphest.php index 21255b6fca..1b69e4c3ef 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryManiphest.php +++ b/src/applications/feed/story/PhabricatorFeedStoryManiphest.php @@ -16,13 +16,11 @@ final class PhabricatorFeedStoryManiphest public function renderView() { $data = $this->getStoryData(); - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('maniphest-dark'); - $view->setViewed($this->getHasViewed()); $line = $this->getLineForData($data); $view->setTitle($line); - $view->setEpoch($data->getEpoch()); $action = $data->getValue('action'); diff --git a/src/applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php b/src/applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php index db2abc05ef..313c1820c5 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php +++ b/src/applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php @@ -54,10 +54,8 @@ final class PhabricatorFeedStoryManiphestAggregate break; } - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('maniphest-dark'); - $view->setEpoch($this->getEpoch()); - $view->setViewed($this->getHasViewed()); $view->setTitle($title); $href = $this->getHandle($data->getValue('taskPHID'))->getURI(); diff --git a/src/applications/feed/story/PhabricatorFeedStoryPhriction.php b/src/applications/feed/story/PhabricatorFeedStoryPhriction.php index 311d61607c..478e7e514a 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryPhriction.php +++ b/src/applications/feed/story/PhabricatorFeedStoryPhriction.php @@ -21,7 +21,7 @@ final class PhabricatorFeedStoryPhriction extends PhabricatorFeedStory { $author_phid = $data->getAuthorPHID(); $document_phid = $data->getValue('phid'); - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('phriction-dark'); $action = $data->getValue('action'); @@ -64,7 +64,6 @@ final class PhabricatorFeedStoryPhriction extends PhabricatorFeedStory { break; } - $view->setEpoch($data->getEpoch()); $view->setImage($this->getHandle($author_phid)->getImageURI()); $content = $this->renderSummary($data->getValue('content')); $view->appendChild($content); diff --git a/src/applications/feed/story/PhabricatorFeedStoryProject.php b/src/applications/feed/story/PhabricatorFeedStoryProject.php index 0cba787e43..fba28197a9 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryProject.php +++ b/src/applications/feed/story/PhabricatorFeedStoryProject.php @@ -24,7 +24,7 @@ final class PhabricatorFeedStoryProject extends PhabricatorFeedStory { public function renderView() { $data = $this->getStoryData(); - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('projects-dark'); $type = $data->getValue('type'); diff --git a/src/applications/feed/story/PhabricatorFeedStoryStatus.php b/src/applications/feed/story/PhabricatorFeedStoryStatus.php index 315beb08e4..425847f918 100644 --- a/src/applications/feed/story/PhabricatorFeedStoryStatus.php +++ b/src/applications/feed/story/PhabricatorFeedStoryStatus.php @@ -11,11 +11,10 @@ final class PhabricatorFeedStoryStatus extends PhabricatorFeedStory { $author_phid = $data->getAuthorPHID(); - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('calendar-dark'); $view->setTitle($this->linkTo($author_phid)); - $view->setEpoch($data->getEpoch()); $view->setImage($this->getHandle($author_phid)->getImageURI()); $content = $this->renderSummary($data->getValue('content'), $len = null); diff --git a/src/applications/tokens/feed/PhabricatorTokenGivenFeedStory.php b/src/applications/tokens/feed/PhabricatorTokenGivenFeedStory.php index 013b735657..e1ec46e0de 100644 --- a/src/applications/tokens/feed/PhabricatorTokenGivenFeedStory.php +++ b/src/applications/tokens/feed/PhabricatorTokenGivenFeedStory.php @@ -15,9 +15,8 @@ final class PhabricatorTokenGivenFeedStory } public function renderView() { - $view = new PHUIFeedStoryView(); + $view = $this->newStoryView(); $view->setAppIcon('token-dark'); - $view->setViewed($this->getHasViewed()); $author_phid = $this->getValue('authorPHID'); $href = $this->getHandle($this->getPrimaryObjectPHID())->getURI(); diff --git a/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php b/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php index 9e529055d8..254616836c 100644 --- a/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php +++ b/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php @@ -32,12 +32,10 @@ class PhabricatorApplicationTransactionFeedStory } public function renderView() { - $view = new PHUIFeedStoryView(); - $view->setViewed($this->getHasViewed()); + $view = $this->newStoryView(); $handle = $this->getHandle($this->getPrimaryObjectPHID()); $view->setHref($handle->getURI()); - $view->setEpoch($this->getPrimaryTransaction()->getDateCreated()); $view->setAppIconFromPHID($handle->getPHID()); diff --git a/src/view/phui/PHUIFeedStoryView.php b/src/view/phui/PHUIFeedStoryView.php index 59f9e3d6fd..35c782ee72 100644 --- a/src/view/phui/PHUIFeedStoryView.php +++ b/src/view/phui/PHUIFeedStoryView.php @@ -14,6 +14,16 @@ final class PHUIFeedStoryView extends AphrontView { private $tokenBar = array(); private $projects = array(); private $actions = array(); + private $chronologicalKey; + + public function setChronologicalKey($chronological_key) { + $this->chronologicalKey = $chronological_key; + return $this; + } + + public function getChronologicalKey() { + return $this->chronologicalKey; + } public function setTitle($title) { $this->title = $title; @@ -184,6 +194,15 @@ final class PHUIFeedStoryView extends AphrontView { $foot = pht('No time specified.'); } + if ($this->chronologicalKey) { + $foot = phutil_tag( + 'a', + array( + 'href' => '/feed/'.$this->chronologicalKey.'/', + ), + $foot); + } + $icon = null; if ($this->appIcon) { $icon = new PHUIIconView(); diff --git a/webroot/rsrc/css/phui/phui-feed-story.css b/webroot/rsrc/css/phui/phui-feed-story.css index 66c2395773..7db6ddd029 100644 --- a/webroot/rsrc/css/phui/phui-feed-story.css +++ b/webroot/rsrc/css/phui/phui-feed-story.css @@ -29,13 +29,17 @@ } .phui-feed-story-foot { - color: #777; font-size: 11px; background: #f7f7f7; padding: 10px; line-height: 14px; } +.phui-feed-story-foot, +.phui-feed-story-foot a { + color: #777; +} + .phui-feed-story-foot .phui-icon-view { float: left; display: inline-block;