mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-28 16:30:59 +01:00
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
This commit is contained in:
parent
7d3b19922c
commit
abe24ff1ab
18 changed files with 99 additions and 30 deletions
|
@ -2235,7 +2235,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'javelin-behavior-pholio-mock-view' =>
|
'javelin-behavior-pholio-mock-view' =>
|
||||||
array(
|
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',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -3806,7 +3806,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'phui-feed-story-css' =>
|
'phui-feed-story-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/253ac568/rsrc/css/phui/phui-feed-story.css',
|
'uri' => '/res/7960f59a/rsrc/css/phui/phui-feed-story.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -1087,6 +1087,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFeedConstants' => 'applications/feed/constants/PhabricatorFeedConstants.php',
|
'PhabricatorFeedConstants' => 'applications/feed/constants/PhabricatorFeedConstants.php',
|
||||||
'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php',
|
'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php',
|
||||||
'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php',
|
'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php',
|
||||||
|
'PhabricatorFeedDetailController' => 'applications/feed/controller/PhabricatorFeedDetailController.php',
|
||||||
'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php',
|
'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php',
|
||||||
'PhabricatorFeedManagementRepublishWorkflow' => 'applications/feed/management/PhabricatorFeedManagementRepublishWorkflow.php',
|
'PhabricatorFeedManagementRepublishWorkflow' => 'applications/feed/management/PhabricatorFeedManagementRepublishWorkflow.php',
|
||||||
'PhabricatorFeedManagementWorkflow' => 'applications/feed/management/PhabricatorFeedManagementWorkflow.php',
|
'PhabricatorFeedManagementWorkflow' => 'applications/feed/management/PhabricatorFeedManagementWorkflow.php',
|
||||||
|
@ -3039,6 +3040,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorFeedController' => 'PhabricatorController',
|
'PhabricatorFeedController' => 'PhabricatorController',
|
||||||
'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'PhabricatorFeedDetailController' => 'PhabricatorFeedController',
|
||||||
'PhabricatorFeedMainController' => 'PhabricatorFeedController',
|
'PhabricatorFeedMainController' => 'PhabricatorFeedController',
|
||||||
'PhabricatorFeedManagementRepublishWorkflow' => 'PhabricatorFeedManagementWorkflow',
|
'PhabricatorFeedManagementRepublishWorkflow' => 'PhabricatorFeedManagementWorkflow',
|
||||||
'PhabricatorFeedManagementWorkflow' => 'PhutilArgumentWorkflow',
|
'PhabricatorFeedManagementWorkflow' => 'PhutilArgumentWorkflow',
|
||||||
|
|
|
@ -22,6 +22,7 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication {
|
||||||
return array(
|
return array(
|
||||||
'/feed/' => array(
|
'/feed/' => array(
|
||||||
'public/' => 'PhabricatorFeedPublicStreamController',
|
'public/' => 'PhabricatorFeedPublicStreamController',
|
||||||
|
'(?P<id>\d+)/' => 'PhabricatorFeedDetailController',
|
||||||
'(?:(?P<filter>[^/]+)/)?' => 'PhabricatorFeedMainController',
|
'(?:(?P<filter>[^/]+)/)?' => 'PhabricatorFeedMainController',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFeedDetailController extends PhabricatorFeedController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->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(
|
||||||
|
'<div class="phabricator-feed-frame">%s</div>',
|
||||||
|
$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,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -258,6 +258,13 @@ abstract class PhabricatorFeedStory implements PhabricatorPolicyInterface {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function newStoryView() {
|
||||||
|
return id(new PHUIFeedStoryView())
|
||||||
|
->setChronologicalKey($this->getChronologicalKey())
|
||||||
|
->setEpoch($this->getEpoch())
|
||||||
|
->setViewed($this->getHasViewed());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
|
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ final class PhabricatorFeedStoryAudit extends PhabricatorFeedStory {
|
||||||
$author_phid = $this->getAuthorPHID();
|
$author_phid = $this->getAuthorPHID();
|
||||||
$commit_phid = $this->getPrimaryObjectPHID();
|
$commit_phid = $this->getPrimaryObjectPHID();
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('audit-dark');
|
$view->setAppIcon('audit-dark');
|
||||||
|
|
||||||
$action = $this->getValue('action');
|
$action = $this->getValue('action');
|
||||||
|
@ -22,8 +22,6 @@ final class PhabricatorFeedStoryAudit extends PhabricatorFeedStory {
|
||||||
$verb,
|
$verb,
|
||||||
$this->linkTo($commit_phid)));
|
$this->linkTo($commit_phid)));
|
||||||
|
|
||||||
$view->setEpoch($this->getEpoch());
|
|
||||||
|
|
||||||
$comments = $this->getValue('content');
|
$comments = $this->getValue('content');
|
||||||
|
|
||||||
$view->setImage($this->getHandle($author_phid)->getImageURI());
|
$view->setImage($this->getHandle($author_phid)->getImageURI());
|
||||||
|
|
|
@ -49,11 +49,10 @@ final class PhabricatorFeedStoryCommit extends PhabricatorFeedStory {
|
||||||
$commit);
|
$commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('differential-dark');
|
$view->setAppIcon('differential-dark');
|
||||||
|
|
||||||
$view->setTitle($title);
|
$view->setTitle($title);
|
||||||
$view->setEpoch($data->getEpoch());
|
|
||||||
|
|
||||||
if ($data->getValue('authorPHID')) {
|
if ($data->getValue('authorPHID')) {
|
||||||
$view->setImage($this->getHandle($data->getAuthorPHID())->getImageURI());
|
$view->setImage($this->getHandle($data->getAuthorPHID())->getImageURI());
|
||||||
|
|
|
@ -9,13 +9,11 @@ final class PhabricatorFeedStoryDifferential extends PhabricatorFeedStory {
|
||||||
public function renderView() {
|
public function renderView() {
|
||||||
$data = $this->getStoryData();
|
$data = $this->getStoryData();
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('differential-dark');
|
$view->setAppIcon('differential-dark');
|
||||||
$view->setViewed($this->getHasViewed());
|
|
||||||
|
|
||||||
$line = $this->getLineForData($data);
|
$line = $this->getLineForData($data);
|
||||||
$view->setTitle($line);
|
$view->setTitle($line);
|
||||||
$view->setEpoch($data->getEpoch());
|
|
||||||
|
|
||||||
$href = $this->getHandle($data->getValue('revision_phid'))->getURI();
|
$href = $this->getHandle($data->getValue('revision_phid'))->getURI();
|
||||||
$view->setHref($href);
|
$view->setHref($href);
|
||||||
|
|
|
@ -54,10 +54,8 @@ final class PhabricatorFeedStoryDifferentialAggregate
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('differential-dark');
|
$view->setAppIcon('differential-dark');
|
||||||
$view->setEpoch($this->getEpoch());
|
|
||||||
$view->setViewed($this->getHasViewed());
|
|
||||||
$view->setTitle($title);
|
$view->setTitle($title);
|
||||||
|
|
||||||
$href = $this->getHandle($data->getValue('revision_phid'))->getURI();
|
$href = $this->getHandle($data->getValue('revision_phid'))->getURI();
|
||||||
|
|
|
@ -16,13 +16,11 @@ final class PhabricatorFeedStoryManiphest
|
||||||
public function renderView() {
|
public function renderView() {
|
||||||
$data = $this->getStoryData();
|
$data = $this->getStoryData();
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('maniphest-dark');
|
$view->setAppIcon('maniphest-dark');
|
||||||
$view->setViewed($this->getHasViewed());
|
|
||||||
|
|
||||||
$line = $this->getLineForData($data);
|
$line = $this->getLineForData($data);
|
||||||
$view->setTitle($line);
|
$view->setTitle($line);
|
||||||
$view->setEpoch($data->getEpoch());
|
|
||||||
|
|
||||||
$action = $data->getValue('action');
|
$action = $data->getValue('action');
|
||||||
|
|
||||||
|
|
|
@ -54,10 +54,8 @@ final class PhabricatorFeedStoryManiphestAggregate
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('maniphest-dark');
|
$view->setAppIcon('maniphest-dark');
|
||||||
$view->setEpoch($this->getEpoch());
|
|
||||||
$view->setViewed($this->getHasViewed());
|
|
||||||
$view->setTitle($title);
|
$view->setTitle($title);
|
||||||
|
|
||||||
$href = $this->getHandle($data->getValue('taskPHID'))->getURI();
|
$href = $this->getHandle($data->getValue('taskPHID'))->getURI();
|
||||||
|
|
|
@ -21,7 +21,7 @@ final class PhabricatorFeedStoryPhriction extends PhabricatorFeedStory {
|
||||||
$author_phid = $data->getAuthorPHID();
|
$author_phid = $data->getAuthorPHID();
|
||||||
$document_phid = $data->getValue('phid');
|
$document_phid = $data->getValue('phid');
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('phriction-dark');
|
$view->setAppIcon('phriction-dark');
|
||||||
|
|
||||||
$action = $data->getValue('action');
|
$action = $data->getValue('action');
|
||||||
|
@ -64,7 +64,6 @@ final class PhabricatorFeedStoryPhriction extends PhabricatorFeedStory {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->setEpoch($data->getEpoch());
|
|
||||||
$view->setImage($this->getHandle($author_phid)->getImageURI());
|
$view->setImage($this->getHandle($author_phid)->getImageURI());
|
||||||
$content = $this->renderSummary($data->getValue('content'));
|
$content = $this->renderSummary($data->getValue('content'));
|
||||||
$view->appendChild($content);
|
$view->appendChild($content);
|
||||||
|
|
|
@ -24,7 +24,7 @@ final class PhabricatorFeedStoryProject extends PhabricatorFeedStory {
|
||||||
public function renderView() {
|
public function renderView() {
|
||||||
$data = $this->getStoryData();
|
$data = $this->getStoryData();
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('projects-dark');
|
$view->setAppIcon('projects-dark');
|
||||||
|
|
||||||
$type = $data->getValue('type');
|
$type = $data->getValue('type');
|
||||||
|
|
|
@ -11,11 +11,10 @@ final class PhabricatorFeedStoryStatus extends PhabricatorFeedStory {
|
||||||
|
|
||||||
$author_phid = $data->getAuthorPHID();
|
$author_phid = $data->getAuthorPHID();
|
||||||
|
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('calendar-dark');
|
$view->setAppIcon('calendar-dark');
|
||||||
|
|
||||||
$view->setTitle($this->linkTo($author_phid));
|
$view->setTitle($this->linkTo($author_phid));
|
||||||
$view->setEpoch($data->getEpoch());
|
|
||||||
$view->setImage($this->getHandle($author_phid)->getImageURI());
|
$view->setImage($this->getHandle($author_phid)->getImageURI());
|
||||||
|
|
||||||
$content = $this->renderSummary($data->getValue('content'), $len = null);
|
$content = $this->renderSummary($data->getValue('content'), $len = null);
|
||||||
|
|
|
@ -15,9 +15,8 @@ final class PhabricatorTokenGivenFeedStory
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderView() {
|
public function renderView() {
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setAppIcon('token-dark');
|
$view->setAppIcon('token-dark');
|
||||||
$view->setViewed($this->getHasViewed());
|
|
||||||
$author_phid = $this->getValue('authorPHID');
|
$author_phid = $this->getValue('authorPHID');
|
||||||
|
|
||||||
$href = $this->getHandle($this->getPrimaryObjectPHID())->getURI();
|
$href = $this->getHandle($this->getPrimaryObjectPHID())->getURI();
|
||||||
|
|
|
@ -32,12 +32,10 @@ class PhabricatorApplicationTransactionFeedStory
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderView() {
|
public function renderView() {
|
||||||
$view = new PHUIFeedStoryView();
|
$view = $this->newStoryView();
|
||||||
$view->setViewed($this->getHasViewed());
|
|
||||||
|
|
||||||
$handle = $this->getHandle($this->getPrimaryObjectPHID());
|
$handle = $this->getHandle($this->getPrimaryObjectPHID());
|
||||||
$view->setHref($handle->getURI());
|
$view->setHref($handle->getURI());
|
||||||
$view->setEpoch($this->getPrimaryTransaction()->getDateCreated());
|
|
||||||
|
|
||||||
$view->setAppIconFromPHID($handle->getPHID());
|
$view->setAppIconFromPHID($handle->getPHID());
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,16 @@ final class PHUIFeedStoryView extends AphrontView {
|
||||||
private $tokenBar = array();
|
private $tokenBar = array();
|
||||||
private $projects = array();
|
private $projects = array();
|
||||||
private $actions = 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) {
|
public function setTitle($title) {
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
|
@ -184,6 +194,15 @@ final class PHUIFeedStoryView extends AphrontView {
|
||||||
$foot = pht('No time specified.');
|
$foot = pht('No time specified.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->chronologicalKey) {
|
||||||
|
$foot = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/feed/'.$this->chronologicalKey.'/',
|
||||||
|
),
|
||||||
|
$foot);
|
||||||
|
}
|
||||||
|
|
||||||
$icon = null;
|
$icon = null;
|
||||||
if ($this->appIcon) {
|
if ($this->appIcon) {
|
||||||
$icon = new PHUIIconView();
|
$icon = new PHUIIconView();
|
||||||
|
|
|
@ -29,13 +29,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.phui-feed-story-foot {
|
.phui-feed-story-foot {
|
||||||
color: #777;
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
background: #f7f7f7;
|
background: #f7f7f7;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phui-feed-story-foot,
|
||||||
|
.phui-feed-story-foot a {
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
.phui-feed-story-foot .phui-icon-view {
|
.phui-feed-story-foot .phui-icon-view {
|
||||||
float: left;
|
float: left;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
Loading…
Reference in a new issue