@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a feed detail/permalink page for feed stories

Summary:
Ref T2852. Asana has one bug which I'm having a little trouble figuring out. I want to get more information to debug it, but I'll need them to run `bin/feed republish <story_id>` to get that data.

Right now, it's incredibly hard to figure out the story ID for feed stories. So mostly this is to make that easier (click permalink; pull it out of the URL), but it also adds a little functionality and cleans the code up a bit.

The page itself could be prettier and maybe some day we'll add comments or whatever, but it seems reasonably functionalish.

Test Plan:
{F49962}

- Also loaded many pages of feed history to check that nothing broke.

Reviewers: btrahan, chad

Reviewed By: chad

CC: chad, aran

Maniphest Tasks: T2852

Differential Revision: https://secure.phabricator.com/D6440

+99 -30
+2 -2
src/__celerity_resource_map__.php
··· 2235 2235 ), 2236 2236 'javelin-behavior-pholio-mock-view' => 2237 2237 array( 2238 - 'uri' => '/res/014eb2bd/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 2238 + 'uri' => '/res/415cd66a/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 2239 2239 'type' => 'js', 2240 2240 'requires' => 2241 2241 array( ··· 3806 3806 ), 3807 3807 'phui-feed-story-css' => 3808 3808 array( 3809 - 'uri' => '/res/253ac568/rsrc/css/phui/phui-feed-story.css', 3809 + 'uri' => '/res/7960f59a/rsrc/css/phui/phui-feed-story.css', 3810 3810 'type' => 'css', 3811 3811 'requires' => 3812 3812 array(
+2
src/__phutil_library_map__.php
··· 1087 1087 'PhabricatorFeedConstants' => 'applications/feed/constants/PhabricatorFeedConstants.php', 1088 1088 'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php', 1089 1089 'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php', 1090 + 'PhabricatorFeedDetailController' => 'applications/feed/controller/PhabricatorFeedDetailController.php', 1090 1091 'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php', 1091 1092 'PhabricatorFeedManagementRepublishWorkflow' => 'applications/feed/management/PhabricatorFeedManagementRepublishWorkflow.php', 1092 1093 'PhabricatorFeedManagementWorkflow' => 'applications/feed/management/PhabricatorFeedManagementWorkflow.php', ··· 3039 3040 'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions', 3040 3041 'PhabricatorFeedController' => 'PhabricatorController', 3041 3042 'PhabricatorFeedDAO' => 'PhabricatorLiskDAO', 3043 + 'PhabricatorFeedDetailController' => 'PhabricatorFeedController', 3042 3044 'PhabricatorFeedMainController' => 'PhabricatorFeedController', 3043 3045 'PhabricatorFeedManagementRepublishWorkflow' => 'PhabricatorFeedManagementWorkflow', 3044 3046 'PhabricatorFeedManagementWorkflow' => 'PhutilArgumentWorkflow',
+1
src/applications/feed/application/PhabricatorApplicationFeed.php
··· 22 22 return array( 23 23 '/feed/' => array( 24 24 'public/' => 'PhabricatorFeedPublicStreamController', 25 + '(?P<id>\d+)/' => 'PhabricatorFeedDetailController', 25 26 '(?:(?P<filter>[^/]+)/)?' => 'PhabricatorFeedMainController', 26 27 ), 27 28 );
+52
src/applications/feed/controller/PhabricatorFeedDetailController.php
··· 1 + <?php 2 + 3 + final class PhabricatorFeedDetailController extends PhabricatorFeedController { 4 + 5 + private $id; 6 + 7 + public function willProcessRequest(array $data) { 8 + $this->id = $data['id']; 9 + } 10 + 11 + public function processRequest() { 12 + $request = $this->getRequest(); 13 + $user = $request->getUser(); 14 + 15 + $story = id(new PhabricatorFeedQuery()) 16 + ->setViewer($user) 17 + ->withChronologicalKeys(array($this->id)) 18 + ->executeOne(); 19 + if (!$story) { 20 + return new Aphront404Response(); 21 + } 22 + 23 + $feed = array($story); 24 + $builder = new PhabricatorFeedBuilder($feed); 25 + $builder->setUser($user); 26 + $feed_view = $builder->buildView(); 27 + 28 + $title = pht('Story'); 29 + 30 + $feed_view = hsprintf( 31 + '<div class="phabricator-feed-frame">%s</div>', 32 + $feed_view); 33 + 34 + $crumbs = $this->buildApplicationCrumbs(); 35 + $crumbs->addCrumb( 36 + id(new PhabricatorCrumbView()) 37 + ->setName($title)); 38 + 39 + 40 + return $this->buildApplicationPage( 41 + array( 42 + $crumbs, 43 + $feed_view, 44 + ), 45 + array( 46 + 'title' => $title, 47 + 'device' => true, 48 + 'dust' => true, 49 + )); 50 + } 51 + 52 + }
+7
src/applications/feed/story/PhabricatorFeedStory.php
··· 258 258 return array(); 259 259 } 260 260 261 + protected function newStoryView() { 262 + return id(new PHUIFeedStoryView()) 263 + ->setChronologicalKey($this->getChronologicalKey()) 264 + ->setEpoch($this->getEpoch()) 265 + ->setViewed($this->getHasViewed()); 266 + } 267 + 261 268 262 269 /* -( PhabricatorPolicyInterface Implementation )-------------------------- */ 263 270
+1 -3
src/applications/feed/story/PhabricatorFeedStoryAudit.php
··· 10 10 $author_phid = $this->getAuthorPHID(); 11 11 $commit_phid = $this->getPrimaryObjectPHID(); 12 12 13 - $view = new PHUIFeedStoryView(); 13 + $view = $this->newStoryView(); 14 14 $view->setAppIcon('audit-dark'); 15 15 16 16 $action = $this->getValue('action'); ··· 21 21 $this->linkTo($author_phid), 22 22 $verb, 23 23 $this->linkTo($commit_phid))); 24 - 25 - $view->setEpoch($this->getEpoch()); 26 24 27 25 $comments = $this->getValue('content'); 28 26
+1 -2
src/applications/feed/story/PhabricatorFeedStoryCommit.php
··· 49 49 $commit); 50 50 } 51 51 52 - $view = new PHUIFeedStoryView(); 52 + $view = $this->newStoryView(); 53 53 $view->setAppIcon('differential-dark'); 54 54 55 55 $view->setTitle($title); 56 - $view->setEpoch($data->getEpoch()); 57 56 58 57 if ($data->getValue('authorPHID')) { 59 58 $view->setImage($this->getHandle($data->getAuthorPHID())->getImageURI());
+1 -3
src/applications/feed/story/PhabricatorFeedStoryDifferential.php
··· 9 9 public function renderView() { 10 10 $data = $this->getStoryData(); 11 11 12 - $view = new PHUIFeedStoryView(); 12 + $view = $this->newStoryView(); 13 13 $view->setAppIcon('differential-dark'); 14 - $view->setViewed($this->getHasViewed()); 15 14 16 15 $line = $this->getLineForData($data); 17 16 $view->setTitle($line); 18 - $view->setEpoch($data->getEpoch()); 19 17 20 18 $href = $this->getHandle($data->getValue('revision_phid'))->getURI(); 21 19 $view->setHref($href);
+1 -3
src/applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php
··· 54 54 break; 55 55 } 56 56 57 - $view = new PHUIFeedStoryView(); 57 + $view = $this->newStoryView(); 58 58 $view->setAppIcon('differential-dark'); 59 - $view->setEpoch($this->getEpoch()); 60 - $view->setViewed($this->getHasViewed()); 61 59 $view->setTitle($title); 62 60 63 61 $href = $this->getHandle($data->getValue('revision_phid'))->getURI();
+1 -3
src/applications/feed/story/PhabricatorFeedStoryManiphest.php
··· 16 16 public function renderView() { 17 17 $data = $this->getStoryData(); 18 18 19 - $view = new PHUIFeedStoryView(); 19 + $view = $this->newStoryView(); 20 20 $view->setAppIcon('maniphest-dark'); 21 - $view->setViewed($this->getHasViewed()); 22 21 23 22 $line = $this->getLineForData($data); 24 23 $view->setTitle($line); 25 - $view->setEpoch($data->getEpoch()); 26 24 27 25 $action = $data->getValue('action'); 28 26
+1 -3
src/applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php
··· 54 54 break; 55 55 } 56 56 57 - $view = new PHUIFeedStoryView(); 57 + $view = $this->newStoryView(); 58 58 $view->setAppIcon('maniphest-dark'); 59 - $view->setEpoch($this->getEpoch()); 60 - $view->setViewed($this->getHasViewed()); 61 59 $view->setTitle($title); 62 60 63 61 $href = $this->getHandle($data->getValue('taskPHID'))->getURI();
+1 -2
src/applications/feed/story/PhabricatorFeedStoryPhriction.php
··· 21 21 $author_phid = $data->getAuthorPHID(); 22 22 $document_phid = $data->getValue('phid'); 23 23 24 - $view = new PHUIFeedStoryView(); 24 + $view = $this->newStoryView(); 25 25 $view->setAppIcon('phriction-dark'); 26 26 27 27 $action = $data->getValue('action'); ··· 64 64 break; 65 65 } 66 66 67 - $view->setEpoch($data->getEpoch()); 68 67 $view->setImage($this->getHandle($author_phid)->getImageURI()); 69 68 $content = $this->renderSummary($data->getValue('content')); 70 69 $view->appendChild($content);
+1 -1
src/applications/feed/story/PhabricatorFeedStoryProject.php
··· 24 24 public function renderView() { 25 25 $data = $this->getStoryData(); 26 26 27 - $view = new PHUIFeedStoryView(); 27 + $view = $this->newStoryView(); 28 28 $view->setAppIcon('projects-dark'); 29 29 30 30 $type = $data->getValue('type');
+1 -2
src/applications/feed/story/PhabricatorFeedStoryStatus.php
··· 11 11 12 12 $author_phid = $data->getAuthorPHID(); 13 13 14 - $view = new PHUIFeedStoryView(); 14 + $view = $this->newStoryView(); 15 15 $view->setAppIcon('calendar-dark'); 16 16 17 17 $view->setTitle($this->linkTo($author_phid)); 18 - $view->setEpoch($data->getEpoch()); 19 18 $view->setImage($this->getHandle($author_phid)->getImageURI()); 20 19 21 20 $content = $this->renderSummary($data->getValue('content'), $len = null);
+1 -2
src/applications/tokens/feed/PhabricatorTokenGivenFeedStory.php
··· 15 15 } 16 16 17 17 public function renderView() { 18 - $view = new PHUIFeedStoryView(); 18 + $view = $this->newStoryView(); 19 19 $view->setAppIcon('token-dark'); 20 - $view->setViewed($this->getHasViewed()); 21 20 $author_phid = $this->getValue('authorPHID'); 22 21 23 22 $href = $this->getHandle($this->getPrimaryObjectPHID())->getURI();
+1 -3
src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php
··· 32 32 } 33 33 34 34 public function renderView() { 35 - $view = new PHUIFeedStoryView(); 36 - $view->setViewed($this->getHasViewed()); 35 + $view = $this->newStoryView(); 37 36 38 37 $handle = $this->getHandle($this->getPrimaryObjectPHID()); 39 38 $view->setHref($handle->getURI()); 40 - $view->setEpoch($this->getPrimaryTransaction()->getDateCreated()); 41 39 42 40 $view->setAppIconFromPHID($handle->getPHID()); 43 41
+19
src/view/phui/PHUIFeedStoryView.php
··· 14 14 private $tokenBar = array(); 15 15 private $projects = array(); 16 16 private $actions = array(); 17 + private $chronologicalKey; 18 + 19 + public function setChronologicalKey($chronological_key) { 20 + $this->chronologicalKey = $chronological_key; 21 + return $this; 22 + } 23 + 24 + public function getChronologicalKey() { 25 + return $this->chronologicalKey; 26 + } 17 27 18 28 public function setTitle($title) { 19 29 $this->title = $title; ··· 182 192 $foot = phabricator_datetime($this->epoch, $this->user); 183 193 } else { 184 194 $foot = pht('No time specified.'); 195 + } 196 + 197 + if ($this->chronologicalKey) { 198 + $foot = phutil_tag( 199 + 'a', 200 + array( 201 + 'href' => '/feed/'.$this->chronologicalKey.'/', 202 + ), 203 + $foot); 185 204 } 186 205 187 206 $icon = null;
+5 -1
webroot/rsrc/css/phui/phui-feed-story.css
··· 29 29 } 30 30 31 31 .phui-feed-story-foot { 32 - color: #777; 33 32 font-size: 11px; 34 33 background: #f7f7f7; 35 34 padding: 10px; 36 35 line-height: 14px; 36 + } 37 + 38 + .phui-feed-story-foot, 39 + .phui-feed-story-foot a { 40 + color: #777; 37 41 } 38 42 39 43 .phui-feed-story-foot .phui-icon-view {