mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-28 08:20:57 +01:00
Update feed on projects, profile.
Summary: Does a few things, standardizes feed a bit more on people, projects. Cleans up Project pages to be more dashboard like. Adds usable mobile support. Remove extenal public feed styles. The Project pages won't win any design awards, but they are much more usable and responsive (mobile). I assume the default view to be workboard still at some point. Test Plan: Test out Profile, Project Profile, Public Feed, normal Feed. Mobile and Chrome. Reviewers: epriestley, btrahan Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D5700
This commit is contained in:
parent
141228343c
commit
6e86a04ab1
14 changed files with 110 additions and 75 deletions
|
@ -2980,7 +2980,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'phabricator-feed-css' =>
|
'phabricator-feed-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/e337f54b/rsrc/css/application/feed/feed.css',
|
'uri' => '/res/6db1087e/rsrc/css/application/feed/feed.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -3212,7 +3212,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'phabricator-profile-css' =>
|
'phabricator-profile-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/a54f47a7/rsrc/css/application/profile/profile-view.css',
|
'uri' => '/res/76766eb6/rsrc/css/application/profile/profile-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -3221,7 +3221,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'phabricator-profile-header-css' =>
|
'phabricator-profile-header-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/1ccc6f0b/rsrc/css/application/profile/profile-header-view.css',
|
'uri' => '/res/a03c1e20/rsrc/css/application/profile/profile-header-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getShortDescription() {
|
public function getShortDescription() {
|
||||||
return 'Review activity.';
|
return pht('Review activity.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIconName() {
|
public function getIconName() {
|
||||||
|
|
|
@ -56,9 +56,8 @@ final class PhabricatorFeedBuilder {
|
||||||
$null_view->appendChild($view);
|
$null_view->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
return id(new AphrontNullView())->appendChild(hsprintf(
|
return id(new AphrontNullView())
|
||||||
'<div class="phabricator-feed-frame">%s</div>',
|
->appendChild($null_view->render());
|
||||||
$null_view->render()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,10 @@ final class PhabricatorFeedMainController extends PhabricatorFeedController {
|
||||||
$feed_view = $builder->buildView();
|
$feed_view = $builder->buildView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$feed_view = hsprintf(
|
||||||
|
'<div class="phabricator-feed-frame">%s</div>',
|
||||||
|
$feed_view);
|
||||||
|
|
||||||
$crumbs = $this
|
$crumbs = $this
|
||||||
->buildApplicationCrumbs($nav)
|
->buildApplicationCrumbs($nav)
|
||||||
->addCrumb(
|
->addCrumb(
|
||||||
|
|
|
@ -25,14 +25,14 @@ final class PhabricatorFeedPublicStreamController
|
||||||
->setFramed(true)
|
->setFramed(true)
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
|
|
||||||
$view = $builder->buildView();
|
$view = hsprintf('<div class="phabricator-public-feed-frame">%s</div>',
|
||||||
|
$builder->buildView());
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
$view,
|
$view,
|
||||||
array(
|
array(
|
||||||
'title' => pht('Public Feed'),
|
'title' => pht('Public Feed'),
|
||||||
'public' => true,
|
'public' => true,
|
||||||
'dust' => true,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
abstract class PhabricatorFeedView extends AphrontView {
|
|
||||||
|
|
||||||
}
|
|
|
@ -179,7 +179,7 @@ final class PhabricatorPeopleProfileController
|
||||||
$blurb = $engine->markupText($blurb);
|
$blurb = $engine->markupText($blurb);
|
||||||
|
|
||||||
$content = hsprintf(
|
$content = hsprintf(
|
||||||
'<div class="phabricator-profile-info-group ml">
|
'<div class="phabricator-profile-info-group profile-wrap-responsive">
|
||||||
<h1 class="phabricator-profile-info-header">%s</h1>
|
<h1 class="phabricator-profile-info-header">%s</h1>
|
||||||
<div class="phabricator-profile-info-pane">
|
<div class="phabricator-profile-info-pane">
|
||||||
<table class="phabricator-profile-info-table">
|
<table class="phabricator-profile-info-table">
|
||||||
|
@ -194,7 +194,7 @@ final class PhabricatorPeopleProfileController
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>'.
|
</div>'.
|
||||||
'<div class="phabricator-profile-info-group ml">
|
'<div class="phabricator-profile-info-group profile-wrap-responsive">
|
||||||
<h1 class="phabricator-profile-info-header">%s</h1>
|
<h1 class="phabricator-profile-info-header">%s</h1>
|
||||||
<div class="phabricator-profile-info-pane">
|
<div class="phabricator-profile-info-pane">
|
||||||
<table class="phabricator-profile-info-table">
|
<table class="phabricator-profile-info-table">
|
||||||
|
@ -234,7 +234,7 @@ final class PhabricatorPeopleProfileController
|
||||||
$view = $builder->buildView();
|
$view = $builder->buildView();
|
||||||
|
|
||||||
return hsprintf(
|
return hsprintf(
|
||||||
'<div class="phabricator-profile-info-group">
|
'<div class="profile-feed profile-wrap-responsive">
|
||||||
%s
|
%s
|
||||||
</div>',
|
</div>',
|
||||||
$view->render());
|
$view->render());
|
||||||
|
|
|
@ -30,16 +30,15 @@ abstract class PhabricatorProjectController extends PhabricatorController {
|
||||||
$edit_uri = '/project/edit/'.$id.'/';
|
$edit_uri = '/project/edit/'.$id.'/';
|
||||||
$members_uri = '/project/members/'.$id.'/';
|
$members_uri = '/project/members/'.$id.'/';
|
||||||
|
|
||||||
|
$nav_view->addLabel(pht('Project'));
|
||||||
$nav_view->addFilter('dashboard', pht('Dashboard'));
|
$nav_view->addFilter('dashboard', pht('Dashboard'));
|
||||||
$nav_view->addFilter('feed', pht('Feed'));
|
|
||||||
$nav_view->addFilter(null, pht('Tasks').' '.$external_arrow, $tasks_uri);
|
$nav_view->addFilter(null, pht('Tasks').' '.$external_arrow, $tasks_uri);
|
||||||
$nav_view->addFilter(null, pht('Wiki').' '.$external_arrow, $phriction_uri);
|
$nav_view->addFilter(null, pht('Wiki').' '.$external_arrow, $phriction_uri);
|
||||||
$nav_view->addFilter('people', pht('People'));
|
|
||||||
$nav_view->addFilter('about', pht('About'));
|
|
||||||
|
|
||||||
$user = $this->getRequest()->getUser();
|
$user = $this->getRequest()->getUser();
|
||||||
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
|
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
|
||||||
|
|
||||||
|
$nav_view->addLabel(pht('Manage'));
|
||||||
if (PhabricatorPolicyFilter::hasCapability($user, $project, $can_edit)) {
|
if (PhabricatorPolicyFilter::hasCapability($user, $project, $can_edit)) {
|
||||||
$nav_view->addFilter('edit', pht("Edit Project"), $edit_uri);
|
$nav_view->addFilter('edit', pht("Edit Project"), $edit_uri);
|
||||||
$nav_view->addFilter('members', pht("Edit Members"), $members_uri);
|
$nav_view->addFilter('members', pht("Edit Members"), $members_uri);
|
||||||
|
@ -61,10 +60,6 @@ abstract class PhabricatorProjectController extends PhabricatorController {
|
||||||
return $nav_view;
|
return $nav_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildApplicationMenu() {
|
|
||||||
return $this->buildSideNavView(null, true)->getMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildSideNavView($filter = null, $for_app = false) {
|
public function buildSideNavView($filter = null, $for_app = false) {
|
||||||
$user = $this->getRequest()->getUser();
|
$user = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
|
|
@ -144,4 +144,8 @@ final class PhabricatorProjectListController
|
||||||
'dust' => true,
|
'dust' => true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildApplicationMenu() {
|
||||||
|
return $this->buildSideNavView(null, true)->getMenu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,8 @@ final class PhabricatorProjectProfileController
|
||||||
|
|
||||||
$query = id(new PhabricatorProjectQuery())
|
$query = id(new PhabricatorProjectQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($this->id));
|
->withIDs(array($this->id))
|
||||||
|
->needMembers(true);
|
||||||
if ($this->page == 'people') {
|
|
||||||
$query->needMembers(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$project = $query->executeOne();
|
$project = $query->executeOne();
|
||||||
$this->project = $project;
|
$this->project = $project;
|
||||||
|
@ -42,34 +39,31 @@ final class PhabricatorProjectProfileController
|
||||||
$this->page = $nav_view->selectFilter($this->page, 'dashboard');
|
$this->page = $nav_view->selectFilter($this->page, 'dashboard');
|
||||||
|
|
||||||
require_celerity_resource('phabricator-profile-css');
|
require_celerity_resource('phabricator-profile-css');
|
||||||
switch ($this->page) {
|
|
||||||
case 'dashboard':
|
|
||||||
$content = $this->renderTasksPage($project, $profile);
|
|
||||||
|
|
||||||
$query = new PhabricatorFeedQuery();
|
$tasks = $this->renderTasksPage($project, $profile);
|
||||||
$query->setFilterPHIDs(
|
|
||||||
array(
|
|
||||||
$project->getPHID(),
|
|
||||||
));
|
|
||||||
$query->setLimit(50);
|
|
||||||
$query->setViewer($this->getRequest()->getUser());
|
|
||||||
$stories = $query->execute();
|
|
||||||
|
|
||||||
$content = hsprintf('%s%s', $content, $this->renderStories($stories));
|
$query = new PhabricatorFeedQuery();
|
||||||
break;
|
$query->setFilterPHIDs(
|
||||||
case 'about':
|
array(
|
||||||
$content = $this->renderAboutPage($project, $profile);
|
$project->getPHID(),
|
||||||
break;
|
));
|
||||||
case 'people':
|
$query->setLimit(50);
|
||||||
$content = $this->renderPeoplePage($project, $profile);
|
$query->setViewer($this->getRequest()->getUser());
|
||||||
break;
|
$stories = $query->execute();
|
||||||
case 'feed':
|
$feed = $this->renderStories($stories);
|
||||||
$content = $this->renderFeedPage($project, $profile);
|
$about = $this->renderAboutPage($project, $profile);
|
||||||
break;
|
$people = $this->renderPeoplePage($project, $profile);
|
||||||
default:
|
$col1 = hsprintf('%s%s', $about, $people);
|
||||||
throw new Exception("Unimplemented filter '{$this->page}'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$content = id(new AphrontMultiColumnView())
|
||||||
|
->addColumn($col1)
|
||||||
|
->addColumn($feed)
|
||||||
|
->setFluidLayout(true);
|
||||||
|
|
||||||
|
$content = hsprintf(
|
||||||
|
'<div class="phabricator-project-layout">%s%s</div>',
|
||||||
|
$tasks,
|
||||||
|
$content);
|
||||||
|
|
||||||
$header = new PhabricatorProfileHeaderView();
|
$header = new PhabricatorProfileHeaderView();
|
||||||
$header->setName($project->getName());
|
$header->setName($project->getName());
|
||||||
|
@ -111,16 +105,15 @@ final class PhabricatorProjectProfileController
|
||||||
}
|
}
|
||||||
|
|
||||||
$header->addAction($action);
|
$header->addAction($action);
|
||||||
|
|
||||||
$nav_view->appendChild($header);
|
$nav_view->appendChild($header);
|
||||||
|
|
||||||
$content = hsprintf('<div style="padding: 1em;">%s</div>', $content);
|
|
||||||
$header->appendChild($content);
|
$header->appendChild($content);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
$nav_view,
|
$nav_view,
|
||||||
array(
|
array(
|
||||||
'title' => pht('%s Project', $project->getName()),
|
'title' => pht('%s Project', $project->getName()),
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,8 +133,8 @@ final class PhabricatorProjectProfileController
|
||||||
$timestamp = phabricator_datetime($project->getDateCreated(), $viewer);
|
$timestamp = phabricator_datetime($project->getDateCreated(), $viewer);
|
||||||
|
|
||||||
$about = hsprintf(
|
$about = hsprintf(
|
||||||
'<div class="phabricator-profile-info-group">
|
'<div class="phabricator-profile-info-group profile-wrap-responsive">
|
||||||
<h1 class="phabricator-profile-info-header">About</h1>
|
<h1 class="phabricator-profile-info-header">%s</h1>
|
||||||
<div class="phabricator-profile-info-pane">
|
<div class="phabricator-profile-info-pane">
|
||||||
<table class="phabricator-profile-info-table">
|
<table class="phabricator-profile-info-table">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -163,6 +156,7 @@ final class PhabricatorProjectProfileController
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>',
|
</div>',
|
||||||
|
pht('About This Project'),
|
||||||
pht('Creator'),
|
pht('Creator'),
|
||||||
$handles[$project->getAuthorPHID()]->renderLink(),
|
$handles[$project->getAuthorPHID()]->renderLink(),
|
||||||
pht('Created'),
|
pht('Created'),
|
||||||
|
@ -194,7 +188,7 @@ final class PhabricatorProjectProfileController
|
||||||
}
|
}
|
||||||
|
|
||||||
return hsprintf(
|
return hsprintf(
|
||||||
'<div class="phabricator-profile-info-group">'.
|
'<div class="phabricator-profile-info-group profile-wrap-responsive">'.
|
||||||
'<h1 class="phabricator-profile-info-header">%s</h1>'.
|
'<h1 class="phabricator-profile-info-header">%s</h1>'.
|
||||||
'<div class="phabricator-profile-info-pane">%s</div>'.
|
'<div class="phabricator-profile-info-pane">%s</div>'.
|
||||||
'</div>',
|
'</div>',
|
||||||
|
@ -227,11 +221,9 @@ final class PhabricatorProjectProfileController
|
||||||
$view = $builder->buildView();
|
$view = $builder->buildView();
|
||||||
|
|
||||||
return hsprintf(
|
return hsprintf(
|
||||||
'<div class="phabricator-profile-info-group">'.
|
'<div class="profile-feed profile-wrap-responsive">'.
|
||||||
'<h1 class="phabricator-profile-info-header">%s</h1>'.
|
'%s'.
|
||||||
'<div class="phabricator-profile-info-pane">%s</div>'.
|
|
||||||
'</div>',
|
'</div>',
|
||||||
pht('Activity Feed'),
|
|
||||||
$view->render());
|
$view->render());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +265,7 @@ final class PhabricatorProjectProfileController
|
||||||
pht("View All Open Tasks \xC2\xBB"));
|
pht("View All Open Tasks \xC2\xBB"));
|
||||||
|
|
||||||
$content = hsprintf(
|
$content = hsprintf(
|
||||||
'<div class="phabricator-profile-info-group">
|
'<div class="phabricator-profile-info-group profile-wrap-responsive">
|
||||||
<h1 class="phabricator-profile-info-header">%s</h1>'.
|
<h1 class="phabricator-profile-info-header">%s</h1>'.
|
||||||
'<div class="phabricator-profile-info-pane">'.
|
'<div class="phabricator-profile-info-pane">'.
|
||||||
'%s'.
|
'%s'.
|
||||||
|
@ -287,4 +279,8 @@ final class PhabricatorProjectProfileController
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildApplicationMenu() {
|
||||||
|
return $this->buildLocalNavigation($this->project)->getMenu();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,13 +100,15 @@ final class PHUIFeedStoryView extends AphrontView {
|
||||||
$body = null;
|
$body = null;
|
||||||
$foot = null;
|
$foot = null;
|
||||||
$image_style = null;
|
$image_style = null;
|
||||||
|
$body_content = $this->renderChildren();
|
||||||
$body = phutil_tag(
|
if ($body_content) {
|
||||||
'div',
|
$body = phutil_tag(
|
||||||
array(
|
'div',
|
||||||
'class' => 'phui-feed-story-body',
|
array(
|
||||||
),
|
'class' => 'phui-feed-story-body',
|
||||||
$this->renderChildren());
|
),
|
||||||
|
$body_content);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->epoch) {
|
if ($this->epoch) {
|
||||||
$foot = phabricator_datetime($this->epoch, $this->user);
|
$foot = phabricator_datetime($this->epoch, $this->user);
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.phabricator-feed-frame {
|
.phabricator-feed-frame {
|
||||||
|
margin: 20px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-public-feed-frame {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.phabricator-feed-frame .phabricator-action-header-title {
|
.phabricator-feed-frame .phabricator-action-header-title {
|
||||||
|
@ -12,8 +17,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-desktop .phabricator-feed-frame {
|
.device-desktop .phabricator-feed-frame {
|
||||||
width: 600px;
|
max-width: 600px;
|
||||||
margin: 20px auto;
|
margin: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.phabricator-feed-story-date-separator {
|
.phabricator-feed-story-date-separator {
|
||||||
|
@ -29,3 +34,15 @@
|
||||||
float: right;
|
float: right;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.phabricator-public-feed-frame .phui-feed-story-foot {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-public-feed-frame .phui-feed-story {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-public-feed-frame .phui-feed-wrap {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: #c0c5d1;
|
border-color: #c0c5d1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.phabricator-profile-header .profile-header-name {
|
.phabricator-profile-header .profile-header-name {
|
||||||
|
|
|
@ -102,3 +102,27 @@ img.phabricator-profile-image {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin: .5em 1em 0;
|
margin: .5em 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profile-wrap-responsive {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device .profile-wrap-responsive {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-desktop .profile-feed {
|
||||||
|
max-width: 640px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-feed .phabricator-action-header-title {
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-desktop .phabricator-project-layout
|
||||||
|
.aphront-multi-column-column-outer:first-child
|
||||||
|
.phabricator-profile-info-group {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue